Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3b1841f6b7 | |||
| b6e8b13d1b | |||
| a13c7cc053 | |||
| 876510bc52 | |||
| 48bf0f549d |
-21
@@ -1,21 +0,0 @@
|
||||
#Editor generated files
|
||||
*.sln
|
||||
*.vcproj
|
||||
*.suo
|
||||
*.ncb
|
||||
*.user
|
||||
|
||||
#Directories
|
||||
Release/
|
||||
Debug/
|
||||
Out/
|
||||
|
||||
#Project generated files
|
||||
*.db
|
||||
*.o
|
||||
*.a
|
||||
*.exe
|
||||
|
||||
#Shell files
|
||||
*.bat
|
||||
*.sh
|
||||
@@ -1,41 +0,0 @@
|
||||
## Outline
|
||||
|
||||
Tortuga is a 2D multiplayer JRPG featuring permadeath, with an emphasis on multiplayer cooperation, exploration and customization. The game runs on customizable public and private servers.
|
||||
|
||||
This game is inspired by classic 2D RPGs (Final Fantasy, The Legend of Zelda), as well as more modern sandboxes amd MMOs (Minecraft, EVE Online). This project is currently independently created and funded, with the goal of creating a game that will engage the players and inspire a large community.
|
||||
|
||||
## Releases
|
||||
|
||||
The most recent stable build for Windows can be found [here](https://dl.dropboxusercontent.com/u/46669050/Tortuga.rar).
|
||||
|
||||
## Documentation
|
||||
|
||||
* [Tortuga Wiki](https://github.com/Ratstail91/Tortuga/wiki) - Full documentation
|
||||
* [Tortuga Bug Tracker](https://github.com/Ratstail91/Tortuga/issues) - A list of all known bugs and issues
|
||||
|
||||
## External Dependencies
|
||||
|
||||
* [SDL 1.2](http://www.libsdl.org/) - Simple DirectMedia Layer API
|
||||
* [SDL_net 1.2](http://www.libsdl.org/projects/SDL_net/) - SDL's networking extension
|
||||
* [lua 5.2](http://www.lua.org/) - The lua programming language
|
||||
* [SQLite3](http://www.sqlite.org/) - A lightweight SQL database engine
|
||||
|
||||
## Tools
|
||||
|
||||
* [WinRAR](http://www.rarlab.com/) - The best compression tool available IMO; only needed for distribution
|
||||
|
||||
## Copyright
|
||||
|
||||
(Future versions (to be determined) may be released under a modified version of the [Uplink Developer's License](http://www.introversion.co.uk/uplink/developer/license.html).)
|
||||
|
||||
The current version of Tortuga is released under the [zlib license](http://en.wikipedia.org/wiki/Zlib_License).
|
||||
|
||||
Copyright (c) 2013-2015 Kayne Ruse
|
||||
|
||||
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.
|
||||
@@ -1,29 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 CHANNELS_HPP_
|
||||
#define CHANNELS_HPP_
|
||||
|
||||
enum Channels {
|
||||
SERVER = 0
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,23 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "terminal_error.hpp"
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 TERMINALERROR_HPP_
|
||||
#define TERMINALERROR_HPP_
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
class terminal_error: public std::runtime_error {
|
||||
public:
|
||||
explicit terminal_error(const std::string& str): runtime_error(str) {}
|
||||
explicit terminal_error(const char* cstr): runtime_error(cstr) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,55 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 BASECHARACTER_HPP_
|
||||
#define BASECHARACTER_HPP_
|
||||
|
||||
//components
|
||||
#include "character_defines.hpp"
|
||||
#include "entity.hpp"
|
||||
|
||||
//std namespace
|
||||
#include <string>
|
||||
|
||||
class BaseCharacter: public Entity {
|
||||
public:
|
||||
BaseCharacter() = default;
|
||||
virtual ~BaseCharacter() = default;
|
||||
|
||||
//graphics
|
||||
void CorrectSprite();
|
||||
|
||||
//metadata
|
||||
int SetOwner(int i);
|
||||
int GetOwner();
|
||||
std::string SetHandle(std::string s);
|
||||
std::string GetHandle() const;
|
||||
std::string SetAvatar(std::string s);
|
||||
std::string GetAvatar() const;
|
||||
|
||||
protected:
|
||||
//metadata
|
||||
int owner;
|
||||
std::string handle;
|
||||
std::string avatar;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,46 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#include "base_monster.hpp"
|
||||
|
||||
#include "config_utility.hpp"
|
||||
|
||||
void BaseMonster::CorrectSprite() {
|
||||
//TODO: (9) BaseMonster::CorrectSprite()
|
||||
}
|
||||
|
||||
std::string BaseMonster::SetHandle(std::string s) {
|
||||
return handle = s;
|
||||
}
|
||||
|
||||
std::string BaseMonster::GetHandle() const {
|
||||
return handle;
|
||||
}
|
||||
|
||||
std::string BaseMonster::SetAvatar(std::string s) {
|
||||
avatar = s;
|
||||
sprite.LoadSurface(ConfigUtility::GetSingleton()["dir.sprites"] + avatar, 4, 1);
|
||||
return avatar;
|
||||
}
|
||||
|
||||
std::string BaseMonster::GetAvatar() const {
|
||||
return avatar;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 BASEMONSTER_HPP_
|
||||
#define BASEMONSTER_HPP_
|
||||
|
||||
#include "entity.hpp"
|
||||
|
||||
class BaseMonster: public Entity {
|
||||
public:
|
||||
BaseMonster() = default;
|
||||
virtual ~BaseMonster() = default;
|
||||
|
||||
void CorrectSprite();
|
||||
|
||||
std::string SetHandle(std::string s);
|
||||
std::string GetHandle() const;
|
||||
std::string SetAvatar(std::string s);
|
||||
std::string GetAvatar() const;
|
||||
|
||||
protected:
|
||||
//metadata
|
||||
std::string handle;
|
||||
std::string avatar;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,63 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
|
||||
SpriteSheet* Entity::GetSprite() {
|
||||
return &sprite;
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//accessors & mutators
|
||||
//-------------------------
|
||||
|
||||
Vector2 Entity::SetOrigin(Vector2 v) {
|
||||
return origin = v;
|
||||
}
|
||||
|
||||
Vector2 Entity::SetMotion(Vector2 v) {
|
||||
return motion = v;
|
||||
}
|
||||
|
||||
BoundingBox Entity::SetBounds(BoundingBox b) {
|
||||
return bounds = b;
|
||||
}
|
||||
|
||||
Vector2 Entity::GetOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
Vector2 Entity::GetMotion() {
|
||||
return motion;
|
||||
}
|
||||
|
||||
BoundingBox Entity::GetBounds() {
|
||||
return bounds;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
#config
|
||||
INCLUDES+=. .. ../../common/gameplay ../../common/graphics ../../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)/,client.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
|
||||
@@ -1,37 +0,0 @@
|
||||
#config
|
||||
INCLUDES+=. .. ../client_utilities ../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))
|
||||
|
||||
#source
|
||||
CXXSRC=$(wildcard *.cpp)
|
||||
|
||||
#objects
|
||||
OBJDIR=obj
|
||||
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
||||
|
||||
#output
|
||||
OUTDIR=..
|
||||
OUT=$(addprefix $(OUTDIR)/,client.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
|
||||
@@ -1,170 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 INWORLD_HPP_
|
||||
#define INWORLD_HPP_
|
||||
|
||||
//maps
|
||||
#include "region_pager_base.hpp"
|
||||
|
||||
//utilities
|
||||
#include "udp_network_utility.hpp"
|
||||
#include "serial_packet.hpp"
|
||||
#include "config_utility.hpp"
|
||||
|
||||
//graphics
|
||||
#include "image.hpp"
|
||||
#include "raster_font.hpp"
|
||||
#include "button.hpp"
|
||||
#include "tile_sheet.hpp"
|
||||
|
||||
//common
|
||||
#include "frame_rate.hpp"
|
||||
|
||||
//client
|
||||
#include "base_scene.hpp"
|
||||
#include "base_monster.hpp"
|
||||
#include "local_character.hpp"
|
||||
|
||||
//STL
|
||||
#include <map>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
class World: public BaseScene {
|
||||
public:
|
||||
//Public access members
|
||||
World(int* const argClientIndex, int* const argAccountIndex);
|
||||
~World();
|
||||
|
||||
protected:
|
||||
//Frame loop
|
||||
void FrameStart();
|
||||
void Update();
|
||||
void FrameEnd();
|
||||
void RenderFrame();
|
||||
void Render(SDL_Surface* const);
|
||||
|
||||
//Event handlers
|
||||
void QuitEvent();
|
||||
void MouseMotion(SDL_MouseMotionEvent const&);
|
||||
void MouseButtonDown(SDL_MouseButtonEvent const&);
|
||||
void MouseButtonUp(SDL_MouseButtonEvent const&);
|
||||
void KeyDown(SDL_KeyboardEvent const&);
|
||||
void KeyUp(SDL_KeyboardEvent const&);
|
||||
|
||||
//handle incoming traffic
|
||||
void HandlePacket(SerialPacket* const);
|
||||
|
||||
//heartbeat system
|
||||
void hPing(ServerPacket* const);
|
||||
void hPong(ServerPacket* const);
|
||||
|
||||
void CheckHeartBeat();
|
||||
|
||||
//basic connections
|
||||
void SendLogoutRequest();
|
||||
void SendDisconnectRequest();
|
||||
void SendAdminDisconnectForced();
|
||||
void SendAdminShutdownRequest();
|
||||
|
||||
void hLogoutResponse(ClientPacket* const);
|
||||
void hDisconnectResponse(ClientPacket* const);
|
||||
void hAdminDisconnectForced(ClientPacket* const);
|
||||
|
||||
//map management
|
||||
void SendRegionRequest(int roomIndex, int x, int y);
|
||||
void hRegionContent(RegionPacket* const);
|
||||
void UpdateMap();
|
||||
|
||||
//character management
|
||||
void hCharacterUpdate(CharacterPacket* const);
|
||||
void hCharacterCreate(CharacterPacket* const);
|
||||
void hCharacterDelete(CharacterPacket* const);
|
||||
void hQueryCharacterExists(CharacterPacket* const);
|
||||
void hQueryCharacterStats(CharacterPacket* const);
|
||||
void hQueryCharacterLocation(CharacterPacket* const);
|
||||
void hCharacterMovement(CharacterPacket* const);
|
||||
void hCharacterAttack(CharacterPacket* const);
|
||||
void hCharacterDamage(CharacterPacket* const);
|
||||
|
||||
//monster management
|
||||
void hMonsterCreate(MonsterPacket* const);
|
||||
void hMonsterDelete(MonsterPacket* const);
|
||||
void hQueryMonsterExists(MonsterPacket* const);
|
||||
void hQueryMonsterStats(MonsterPacket* const);
|
||||
void hQueryMonsterLocation(MonsterPacket* const);
|
||||
void hMonsterMovement(MonsterPacket* const);
|
||||
void hMonsterAttack(MonsterPacket* const);
|
||||
void hMonsterDamage(MonsterPacket* const);
|
||||
|
||||
//chat
|
||||
void hTextBroadcast(TextPacket* const);
|
||||
void hTextSpeech(TextPacket* const);
|
||||
void hTextWhisper(TextPacket* const);
|
||||
|
||||
//general gameplay
|
||||
void SendLocalCharacterMovement();
|
||||
std::list<BoundingBox> GenerateCollisionGrid(Entity*, int tileWidth, int tileHeight);
|
||||
|
||||
//indexes
|
||||
int& clientIndex;
|
||||
int& accountIndex;
|
||||
int characterIndex = -1;
|
||||
int roomIndex = -1;
|
||||
|
||||
//graphics
|
||||
Image buttonImage;
|
||||
RasterFont font;
|
||||
TileSheet tileSheet;
|
||||
|
||||
//map
|
||||
RegionPagerBase regionPager;
|
||||
|
||||
//UI
|
||||
Button disconnectButton;
|
||||
Button shutDownButton;
|
||||
FrameRate fps;
|
||||
|
||||
//the camera structure
|
||||
struct {
|
||||
int x = 0, y = 0;
|
||||
int width = 0, height = 0;
|
||||
int marginX = 0, marginY = 0;
|
||||
} camera;
|
||||
|
||||
//entities
|
||||
std::map<int, BaseCharacter> characterMap;
|
||||
std::map<int, BaseMonster> monsterMap;
|
||||
LocalCharacter* localCharacter = nullptr;
|
||||
|
||||
//heartbeat
|
||||
//TODO: (2) Heartbeat needs it's own utility
|
||||
typedef std::chrono::steady_clock Clock;
|
||||
Clock::time_point lastBeat = Clock::now();
|
||||
int attemptedBeats = 0;
|
||||
|
||||
//ugly references; I hate this
|
||||
ConfigUtility& config = ConfigUtility::GetSingleton();
|
||||
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,239 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "world.hpp"
|
||||
|
||||
#include "channels.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
//-------------------------
|
||||
//character management
|
||||
//-------------------------
|
||||
|
||||
//DOCS: preexisting characters will result in query responses
|
||||
//DOCS: new characters will result in create messages
|
||||
//DOCS: this client's character will exist in both (skipped)
|
||||
|
||||
void World::hCharacterUpdate(CharacterPacket* const argPacket) {
|
||||
//TODO: (1) Authentication
|
||||
//NOTE: applies to the local character too
|
||||
|
||||
//check that this character exists
|
||||
std::map<int, BaseCharacter>::iterator characterIt = characterMap.find(argPacket->characterIndex);
|
||||
if (characterIt != characterMap.end()) {
|
||||
//update the origin and motion, if there's a difference
|
||||
if (characterIt->second.GetOrigin() != argPacket->origin) {
|
||||
characterIt->second.SetOrigin(argPacket->origin);
|
||||
}
|
||||
if (characterIt->second.GetMotion() != argPacket->motion) {
|
||||
characterIt->second.SetMotion(argPacket->motion);
|
||||
characterIt->second.CorrectSprite(); //only correct the sprite if the motion changes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void World::hCharacterCreate(CharacterPacket* const argPacket) {
|
||||
//prevent double message
|
||||
if (characterMap.find(argPacket->characterIndex) != characterMap.end()) {
|
||||
std::ostringstream msg;
|
||||
msg << "Double character creation event; ";
|
||||
msg << "Index: " << argPacket->characterIndex << "; ";
|
||||
msg << "Handle: " << argPacket->handle;
|
||||
throw(std::runtime_error(msg.str()));
|
||||
}
|
||||
|
||||
//implicity create and retrieve the entity
|
||||
BaseCharacter* character = &characterMap[argPacket->characterIndex];
|
||||
|
||||
//fill the character's info
|
||||
character->SetHandle(argPacket->handle);
|
||||
character->SetAvatar(argPacket->avatar);
|
||||
character->SetOwner(argPacket->accountIndex);
|
||||
character->SetOrigin(argPacket->origin);
|
||||
character->SetMotion(argPacket->motion);
|
||||
character->SetBounds(argPacket->bounds);
|
||||
|
||||
character->CorrectSprite();
|
||||
|
||||
//check for this player's character
|
||||
if (character->GetOwner() == accountIndex) {
|
||||
localCharacter = static_cast<LocalCharacter*>(character);
|
||||
|
||||
//focus the camera on this character's sprite
|
||||
camera.marginX = (camera.width / 2 - localCharacter->GetSprite()->GetImage()->GetClipW() / 2);
|
||||
camera.marginY = (camera.height/ 2 - localCharacter->GetSprite()->GetImage()->GetClipH() / 2);
|
||||
|
||||
//focus on this character's info
|
||||
characterIndex = argPacket->characterIndex;
|
||||
roomIndex = argPacket->roomIndex;
|
||||
|
||||
//query the world state (room)
|
||||
CharacterPacket newPacket;
|
||||
memset(&newPacket, 0, MAX_PACKET_SIZE);
|
||||
newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS;
|
||||
newPacket.roomIndex = roomIndex;
|
||||
network.SendTo(Channels::SERVER, &newPacket);
|
||||
newPacket.type = SerialPacketType::QUERY_MONSTER_EXISTS;
|
||||
network.SendTo(Channels::SERVER, &newPacket);
|
||||
}
|
||||
|
||||
//debug
|
||||
std::cout << "Character Create, total: " << characterMap.size() << std::endl;
|
||||
}
|
||||
|
||||
void World::hCharacterDelete(CharacterPacket* const argPacket) {
|
||||
//ignore if this character doesn't exist
|
||||
std::map<int, BaseCharacter>::iterator characterIt = characterMap.find(argPacket->characterIndex);
|
||||
if (characterIt == characterMap.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//check for this player's character
|
||||
if ((*characterIt).second.GetOwner() == accountIndex) {
|
||||
localCharacter = nullptr;
|
||||
|
||||
//clear the camera
|
||||
camera.marginX = 0;
|
||||
camera.marginY = 0;
|
||||
|
||||
//clear the room
|
||||
roomIndex = -1;
|
||||
regionPager.UnloadAll();
|
||||
characterMap.clear();
|
||||
monsterMap.clear();
|
||||
}
|
||||
else {
|
||||
//remove this character
|
||||
characterMap.erase(characterIt);
|
||||
}
|
||||
|
||||
//debug
|
||||
std::cout << "Character Delete, total: " << characterMap.size() << std::endl;
|
||||
}
|
||||
|
||||
void World::hQueryCharacterExists(CharacterPacket* const argPacket) {
|
||||
//prevent a double message about this player's character
|
||||
// if (argPacket->accountIndex == accountIndex) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
//ignore characters in a different room (sub-optimal)
|
||||
if (argPacket->roomIndex != roomIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
//implicitly construct the character if it doesn't exist
|
||||
BaseCharacter* character = &characterMap[argPacket->characterIndex];
|
||||
|
||||
//set/update the character's info
|
||||
character->SetOrigin(argPacket->origin);
|
||||
character->SetMotion(argPacket->motion);
|
||||
character->SetBounds({CHARACTER_BOUNDS_X, CHARACTER_BOUNDS_Y, CHARACTER_BOUNDS_WIDTH, CHARACTER_BOUNDS_HEIGHT});
|
||||
character->SetHandle(argPacket->handle);
|
||||
character->SetAvatar(argPacket->avatar);
|
||||
character->SetOwner(argPacket->accountIndex);
|
||||
character->CorrectSprite();
|
||||
|
||||
//debug
|
||||
std::cout << "Character Query, total: " << characterMap.size() << std::endl;
|
||||
}
|
||||
|
||||
void World::hQueryCharacterStats(CharacterPacket* const argPacket) {
|
||||
//TODO: (9) World::hQueryCharacterStats()
|
||||
}
|
||||
|
||||
void World::hQueryCharacterLocation(CharacterPacket* const argPacket) {
|
||||
//TODO: (9) World::hQueryCharacterLocation()
|
||||
}
|
||||
|
||||
void World::hCharacterMovement(CharacterPacket* const argPacket) {
|
||||
//TODO: (1) Authentication
|
||||
if (argPacket->characterIndex == characterIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
//check that this character exists
|
||||
std::map<int, BaseCharacter>::iterator characterIt = characterMap.find(argPacket->characterIndex);
|
||||
if (characterIt != characterMap.end()) {
|
||||
//set the origin and motion
|
||||
characterIt->second.SetOrigin(argPacket->origin);
|
||||
characterIt->second.SetMotion(argPacket->motion);
|
||||
characterIt->second.CorrectSprite();
|
||||
}
|
||||
}
|
||||
|
||||
void World::hCharacterAttack(CharacterPacket* const argPacket) {
|
||||
//TODO: (9) World::hCharacterAttack()
|
||||
}
|
||||
|
||||
void World::hCharacterDamage(CharacterPacket* const argPacket) {
|
||||
//TODO: (9) World::hCharacterDamage()
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//player movement & collision
|
||||
//-------------------------
|
||||
|
||||
void World::SendLocalCharacterMovement() {
|
||||
CharacterPacket newPacket;
|
||||
newPacket.type = SerialPacketType::CHARACTER_MOVEMENT;
|
||||
|
||||
newPacket.accountIndex = accountIndex;
|
||||
newPacket.characterIndex = characterIndex;
|
||||
newPacket.roomIndex = roomIndex;
|
||||
newPacket.origin = localCharacter->GetOrigin();
|
||||
newPacket.motion = localCharacter->GetMotion();
|
||||
|
||||
network.SendTo(Channels::SERVER, &newPacket);
|
||||
}
|
||||
|
||||
std::list<BoundingBox> World::GenerateCollisionGrid(Entity* ptr, int tileWidth, int tileHeight) {
|
||||
//prepare for collisions
|
||||
BoundingBox wallBounds = {0, 0, tileWidth, tileHeight};
|
||||
std::list<BoundingBox> boxList;
|
||||
|
||||
//NOTE: for loops were too dense to work with, so I've just used while loops
|
||||
|
||||
//outer loop
|
||||
wallBounds.x = snapToBase((double)wallBounds.w, ptr->GetOrigin().x);
|
||||
while(wallBounds.x < (ptr->GetOrigin() + ptr->GetBounds()).x + ptr->GetBounds().w) {
|
||||
//inner loop
|
||||
wallBounds.y = snapToBase((double)wallBounds.h, ptr->GetOrigin().y);
|
||||
while(wallBounds.y < (ptr->GetOrigin() + ptr->GetBounds()).y + ptr->GetBounds().h) {
|
||||
//check to see if this tile is solid
|
||||
if (regionPager.GetSolid(wallBounds.x / wallBounds.w, wallBounds.y / wallBounds.h)) {
|
||||
//push onto the box set
|
||||
boxList.push_front(wallBounds);
|
||||
}
|
||||
|
||||
//increment
|
||||
wallBounds.y += wallBounds.h;
|
||||
}
|
||||
|
||||
//increment
|
||||
wallBounds.x += wallBounds.w;
|
||||
}
|
||||
|
||||
return std::move(boxList);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "world.hpp"
|
||||
|
||||
//-------------------------
|
||||
//chat
|
||||
//-------------------------
|
||||
|
||||
void World::hTextBroadcast(TextPacket* const argPacket) {
|
||||
//TODO: (9) World::hTextBroadcast()
|
||||
}
|
||||
|
||||
void World::hTextSpeech(TextPacket* const argPacket) {
|
||||
//TODO: (9) World::hTextSpeech()
|
||||
}
|
||||
|
||||
void World::hTextWhisper(TextPacket* const argPacket) {
|
||||
//TODO: (9) World::hTextWhisper()
|
||||
}
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "world.hpp"
|
||||
|
||||
#include "channels.hpp"
|
||||
#include "ip_operators.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
//-------------------------
|
||||
//heartbeat system
|
||||
//-------------------------
|
||||
|
||||
void World::hPing(ServerPacket* const argPacket) {
|
||||
ServerPacket newPacket;
|
||||
newPacket.type = SerialPacketType::PONG;
|
||||
network.SendTo(argPacket->srcAddress, &newPacket);
|
||||
}
|
||||
|
||||
void World::hPong(ServerPacket* const argPacket) {
|
||||
if (*network.GetIPAddress(Channels::SERVER) != argPacket->srcAddress) {
|
||||
throw(std::runtime_error("Heartbeat message received from an unknown source"));
|
||||
}
|
||||
attemptedBeats = 0;
|
||||
lastBeat = Clock::now();
|
||||
}
|
||||
|
||||
void World::CheckHeartBeat() {
|
||||
//check the connection (heartbeat)
|
||||
if (Clock::now() - lastBeat > std::chrono::seconds(3)) {
|
||||
if (attemptedBeats > 2) {
|
||||
//escape to the disconnect screen
|
||||
SendDisconnectRequest();
|
||||
SetNextScene(SceneList::DISCONNECTEDSCREEN);
|
||||
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "Error: Lost connection to the server";
|
||||
}
|
||||
else {
|
||||
ServerPacket newPacket;
|
||||
newPacket.type = SerialPacketType::PING;
|
||||
network.SendTo(Channels::SERVER, &newPacket);
|
||||
|
||||
attemptedBeats++;
|
||||
lastBeat = Clock::now();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Connection control
|
||||
//-------------------------
|
||||
|
||||
void World::SendLogoutRequest() {
|
||||
ClientPacket newPacket;
|
||||
|
||||
//send a logout request
|
||||
newPacket.type = SerialPacketType::LOGOUT_REQUEST;
|
||||
newPacket.accountIndex = accountIndex;
|
||||
|
||||
network.SendTo(Channels::SERVER, &newPacket);
|
||||
}
|
||||
|
||||
void World::SendDisconnectRequest() {
|
||||
ClientPacket newPacket;
|
||||
|
||||
//send a disconnect request
|
||||
newPacket.type = SerialPacketType::DISCONNECT_REQUEST;
|
||||
newPacket.clientIndex = clientIndex;
|
||||
|
||||
network.SendTo(Channels::SERVER, &newPacket);
|
||||
}
|
||||
|
||||
void World::SendAdminDisconnectForced() {
|
||||
//TODO: (9) World::SendAdminDisconnectForced()
|
||||
}
|
||||
|
||||
void World::SendAdminShutdownRequest() {
|
||||
ClientPacket newPacket;
|
||||
|
||||
//send a shutdown request
|
||||
newPacket.type = SerialPacketType::ADMIN_SHUTDOWN_REQUEST;
|
||||
newPacket.accountIndex = accountIndex;
|
||||
|
||||
network.SendTo(Channels::SERVER, &newPacket);
|
||||
}
|
||||
|
||||
void World::hLogoutResponse(ClientPacket* const argPacket) {
|
||||
if (localCharacter) {
|
||||
characterMap.erase(characterIndex);
|
||||
localCharacter = nullptr;
|
||||
}
|
||||
|
||||
accountIndex = -1;
|
||||
characterIndex = -1;
|
||||
|
||||
//reset the camera
|
||||
camera.marginX = camera.marginY = 0;
|
||||
|
||||
//because, why not? I guess...
|
||||
SendDisconnectRequest();
|
||||
}
|
||||
|
||||
void World::hDisconnectResponse(ClientPacket* const argPacket) {
|
||||
hLogoutResponse(argPacket);//shortcut
|
||||
SetNextScene(SceneList::DISCONNECTEDSCREEN);
|
||||
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have successfully logged out";
|
||||
}
|
||||
|
||||
void World::hAdminDisconnectForced(ClientPacket* const argPacket) {
|
||||
hDisconnectResponse(argPacket);//shortcut
|
||||
SetNextScene(SceneList::DISCONNECTEDSCREEN);
|
||||
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have been forcibly disconnected by the server";
|
||||
}
|
||||
|
||||
@@ -1,414 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "world.hpp"
|
||||
|
||||
#include "channels.hpp"
|
||||
|
||||
#include "terminal_error.hpp"
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
//-------------------------
|
||||
//Public access members
|
||||
//-------------------------
|
||||
|
||||
World::World(int* const argClientIndex, int* const argAccountIndex):
|
||||
clientIndex(*argClientIndex),
|
||||
accountIndex(*argAccountIndex)
|
||||
{
|
||||
//setup the utility objects
|
||||
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
|
||||
buttonImage.SetClipH(buttonImage.GetClipH()/3);
|
||||
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
|
||||
|
||||
//pass the utility objects
|
||||
disconnectButton.SetImage(&buttonImage);
|
||||
disconnectButton.SetFont(&font);
|
||||
shutDownButton.SetImage(&buttonImage);
|
||||
shutDownButton.SetFont(&font);
|
||||
|
||||
//set the button positions
|
||||
disconnectButton.SetX(50);
|
||||
disconnectButton.SetY(50 + buttonImage.GetClipH() * 0);
|
||||
shutDownButton.SetX(50);
|
||||
shutDownButton.SetY(50 + buttonImage.GetClipH() * 1);
|
||||
|
||||
//set the button texts
|
||||
disconnectButton.SetText("Disconnect");
|
||||
shutDownButton.SetText("Shut Down");
|
||||
|
||||
//load the tilesheet
|
||||
//TODO: (2) Tile size and tile sheet should be loaded elsewhere
|
||||
tileSheet.Load(config["dir.tilesets"] + "overworld.bmp", 32, 32);
|
||||
|
||||
//Send the character data
|
||||
CharacterPacket newPacket;
|
||||
newPacket.type = SerialPacketType::CHARACTER_LOAD;
|
||||
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);
|
||||
|
||||
//set the camera's values
|
||||
camera.width = GetScreen()->w;
|
||||
camera.height = GetScreen()->h;
|
||||
|
||||
//debug
|
||||
//
|
||||
}
|
||||
|
||||
World::~World() {
|
||||
//unload the local data
|
||||
characterMap.clear();
|
||||
monsterMap.clear();
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Frame loop
|
||||
//-------------------------
|
||||
|
||||
void World::FrameStart() {
|
||||
//
|
||||
}
|
||||
|
||||
void World::Update() {
|
||||
//create and zero the buffer
|
||||
SerialPacket* packetBuffer = reinterpret_cast<SerialPacket*>(new char[MAX_PACKET_SIZE]);
|
||||
memset(packetBuffer, 0, MAX_PACKET_SIZE);
|
||||
|
||||
try {
|
||||
//suck in and process all waiting packets
|
||||
while(network.Receive(packetBuffer)) {
|
||||
HandlePacket(packetBuffer);
|
||||
}
|
||||
}
|
||||
catch(terminal_error& e) {
|
||||
throw(e);
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
std::cerr << "HandlePacket Error: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
//free the buffer
|
||||
delete reinterpret_cast<char*>(packetBuffer);
|
||||
|
||||
//heartbeat system
|
||||
CheckHeartBeat();
|
||||
|
||||
//update all entities
|
||||
for (auto& it : characterMap) {
|
||||
it.second.Update();
|
||||
}
|
||||
for (auto& it : monsterMap) {
|
||||
it.second.Update();
|
||||
}
|
||||
|
||||
//update the map
|
||||
UpdateMap();
|
||||
|
||||
//skip the rest without a local character
|
||||
if (!localCharacter) {
|
||||
return;
|
||||
}
|
||||
|
||||
//get the collidable boxes
|
||||
std::list<BoundingBox> boxList = GenerateCollisionGrid(localCharacter, tileSheet.GetTileW(), tileSheet.GetTileH());
|
||||
|
||||
//process the collisions
|
||||
if (localCharacter->ProcessCollisionGrid(boxList)) {
|
||||
localCharacter->CorrectSprite();
|
||||
SendLocalCharacterMovement();
|
||||
}
|
||||
|
||||
//update the camera
|
||||
camera.x = localCharacter->GetOrigin().x - camera.marginX;
|
||||
camera.y = localCharacter->GetOrigin().y - camera.marginY;
|
||||
}
|
||||
|
||||
void World::FrameEnd() {
|
||||
//
|
||||
}
|
||||
|
||||
void World::RenderFrame() {
|
||||
// SDL_FillRect(GetScreen(), 0, 0);
|
||||
Render(GetScreen());
|
||||
SDL_Flip(GetScreen());
|
||||
fps.Calculate();
|
||||
}
|
||||
|
||||
void World::Render(SDL_Surface* const screen) {
|
||||
//draw the map
|
||||
for (std::list<Region>::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) {
|
||||
tileSheet.DrawRegionTo(screen, &(*it), camera.x, camera.y);
|
||||
}
|
||||
|
||||
//draw the entities
|
||||
for (auto& it : characterMap) {
|
||||
//BUG: #29 Characters (and other entities) are drawn out of order
|
||||
it.second.DrawTo(screen, camera.x, camera.y);
|
||||
}
|
||||
for (auto& it : monsterMap) {
|
||||
it.second.DrawTo(screen, camera.x, camera.y);
|
||||
}
|
||||
|
||||
//draw UI
|
||||
disconnectButton.DrawTo(screen);
|
||||
shutDownButton.DrawTo(screen);
|
||||
std::ostringstream msg;
|
||||
msg << fps.GetFrameRate();
|
||||
font.DrawStringTo(msg.str(), screen, 0, 0);
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Event handlers
|
||||
//-------------------------
|
||||
|
||||
void World::QuitEvent() {
|
||||
//two-step logout
|
||||
SendDisconnectRequest();
|
||||
SetNextScene(SceneList::QUIT);
|
||||
}
|
||||
|
||||
void World::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
||||
disconnectButton.MouseMotion(motion);
|
||||
shutDownButton.MouseMotion(motion);
|
||||
}
|
||||
|
||||
void World::MouseButtonDown(SDL_MouseButtonEvent const& button) {
|
||||
disconnectButton.MouseButtonDown(button);
|
||||
shutDownButton.MouseButtonDown(button);
|
||||
}
|
||||
|
||||
void World::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
||||
if (disconnectButton.MouseButtonUp(button) == Button::State::HOVER && button.button == SDL_BUTTON_LEFT) {
|
||||
SendLogoutRequest();
|
||||
}
|
||||
if (shutDownButton.MouseButtonUp(button) == Button::State::HOVER && button.button == SDL_BUTTON_LEFT) {
|
||||
SendAdminShutdownRequest();
|
||||
}
|
||||
}
|
||||
|
||||
void World::KeyDown(SDL_KeyboardEvent const& key) {
|
||||
//hotkeys
|
||||
switch(key.keysym.sym) {
|
||||
case SDLK_ESCAPE:
|
||||
//TODO: (3) the escape key should actually control menus and stuff
|
||||
SendLogoutRequest();
|
||||
return;
|
||||
}
|
||||
|
||||
//character movement
|
||||
if (!localCharacter) {
|
||||
return;
|
||||
}
|
||||
Vector2 motion = localCharacter->GetMotion();
|
||||
switch(key.keysym.sym) {
|
||||
case SDLK_w:
|
||||
motion.y -= CHARACTER_WALKING_SPEED;
|
||||
break;
|
||||
case SDLK_a:
|
||||
motion.x -= CHARACTER_WALKING_SPEED;
|
||||
break;
|
||||
case SDLK_s:
|
||||
motion.y += CHARACTER_WALKING_SPEED;
|
||||
break;
|
||||
case SDLK_d:
|
||||
motion.x += CHARACTER_WALKING_SPEED;
|
||||
break;
|
||||
default:
|
||||
//DOCS: prevents wrong keys screwing with character movement
|
||||
return;
|
||||
}
|
||||
//handle diagonals
|
||||
if (motion.x != 0 && motion.y != 0) {
|
||||
motion *= CHARACTER_WALKING_MOD;
|
||||
}
|
||||
//set the info
|
||||
localCharacter->SetMotion(motion);
|
||||
localCharacter->CorrectSprite();
|
||||
SendLocalCharacterMovement();
|
||||
}
|
||||
|
||||
void World::KeyUp(SDL_KeyboardEvent const& key) {
|
||||
//character movement
|
||||
if (!localCharacter) {
|
||||
return;
|
||||
}
|
||||
Vector2 motion = localCharacter->GetMotion();
|
||||
switch(key.keysym.sym) {
|
||||
case SDLK_w:
|
||||
motion.y = std::min(0.0, motion.y += CHARACTER_WALKING_SPEED);
|
||||
break;
|
||||
case SDLK_a:
|
||||
motion.x = std::min(0.0, motion.x += CHARACTER_WALKING_SPEED);
|
||||
break;
|
||||
case SDLK_s:
|
||||
motion.y = std::max(0.0, motion.y -= CHARACTER_WALKING_SPEED);
|
||||
break;
|
||||
case SDLK_d:
|
||||
motion.x = std::max(0.0, motion.x -= CHARACTER_WALKING_SPEED);
|
||||
break;
|
||||
default:
|
||||
//DOCS: prevents wrong keys screwing with character movement
|
||||
return;
|
||||
}
|
||||
//BUGFIX: reset cardinal direction speed on key release
|
||||
if (motion.x > 0) {
|
||||
motion.x = CHARACTER_WALKING_SPEED;
|
||||
}
|
||||
else if (motion.x < 0) {
|
||||
motion.x = -CHARACTER_WALKING_SPEED;
|
||||
}
|
||||
if (motion.y > 0) {
|
||||
motion.y = CHARACTER_WALKING_SPEED;
|
||||
}
|
||||
else if (motion.y < 0) {
|
||||
motion.y = -CHARACTER_WALKING_SPEED;
|
||||
}
|
||||
//handle diagonals
|
||||
if (motion.x != 0 && motion.y != 0) {
|
||||
motion *= CHARACTER_WALKING_MOD;
|
||||
}
|
||||
//set the info
|
||||
localCharacter->SetMotion(motion);
|
||||
localCharacter->CorrectSprite();
|
||||
SendLocalCharacterMovement();
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Direct incoming traffic
|
||||
//-------------------------
|
||||
|
||||
void World::HandlePacket(SerialPacket* const argPacket) {
|
||||
switch(argPacket->type) {
|
||||
//heartbeat system
|
||||
case SerialPacketType::PING:
|
||||
hPing(static_cast<ServerPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::PONG:
|
||||
hPong(static_cast<ServerPacket*>(argPacket));
|
||||
break;
|
||||
|
||||
//game server connections
|
||||
case SerialPacketType::LOGOUT_RESPONSE:
|
||||
hLogoutResponse(static_cast<ClientPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::DISCONNECT_RESPONSE:
|
||||
hDisconnectResponse(static_cast<ClientPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::ADMIN_DISCONNECT_FORCED:
|
||||
hAdminDisconnectForced(static_cast<ClientPacket*>(argPacket));
|
||||
break;
|
||||
|
||||
//map management
|
||||
case SerialPacketType::REGION_CONTENT:
|
||||
hRegionContent(static_cast<RegionPacket*>(argPacket));
|
||||
break;
|
||||
|
||||
//character management
|
||||
case SerialPacketType::CHARACTER_UPDATE:
|
||||
hCharacterUpdate(static_cast<CharacterPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::CHARACTER_CREATE:
|
||||
hCharacterCreate(static_cast<CharacterPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::CHARACTER_DELETE:
|
||||
hCharacterDelete(static_cast<CharacterPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::QUERY_CHARACTER_EXISTS:
|
||||
hQueryCharacterExists(static_cast<CharacterPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::QUERY_CHARACTER_STATS:
|
||||
hQueryCharacterStats(static_cast<CharacterPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::QUERY_CHARACTER_LOCATION:
|
||||
hQueryCharacterLocation(static_cast<CharacterPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::CHARACTER_MOVEMENT:
|
||||
hCharacterMovement(static_cast<CharacterPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::CHARACTER_ATTACK:
|
||||
hCharacterAttack(static_cast<CharacterPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::CHARACTER_DAMAGE:
|
||||
hCharacterDamage(static_cast<CharacterPacket*>(argPacket));
|
||||
break;
|
||||
|
||||
//monster management
|
||||
case SerialPacketType::MONSTER_CREATE:
|
||||
hMonsterCreate(static_cast<MonsterPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::MONSTER_DELETE:
|
||||
hMonsterDelete(static_cast<MonsterPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::QUERY_MONSTER_EXISTS:
|
||||
hQueryMonsterExists(static_cast<MonsterPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::QUERY_MONSTER_STATS:
|
||||
hQueryMonsterStats(static_cast<MonsterPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::QUERY_MONSTER_LOCATION:
|
||||
hQueryMonsterLocation(static_cast<MonsterPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::MONSTER_MOVEMENT:
|
||||
hMonsterMovement(static_cast<MonsterPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::MONSTER_ATTACK:
|
||||
hMonsterAttack(static_cast<MonsterPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::MONSTER_DAMAGE:
|
||||
hMonsterDamage(static_cast<MonsterPacket*>(argPacket));
|
||||
break;
|
||||
|
||||
//chat
|
||||
case SerialPacketType::TEXT_BROADCAST:
|
||||
hTextBroadcast(static_cast<TextPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::TEXT_SPEECH:
|
||||
hTextSpeech(static_cast<TextPacket*>(argPacket));
|
||||
break;
|
||||
case SerialPacketType::TEXT_WHISPER:
|
||||
hTextWhisper(static_cast<TextPacket*>(argPacket));
|
||||
break;
|
||||
|
||||
//general rejection messages
|
||||
case SerialPacketType::REGION_REJECTION:
|
||||
case SerialPacketType::CHARACTER_REJECTION:
|
||||
case SerialPacketType::QUERY_REJECTION:
|
||||
throw(terminal_error(static_cast<TextPacket*>(argPacket)->text));
|
||||
break;
|
||||
case SerialPacketType::SHUTDOWN_REJECTION:
|
||||
throw(std::runtime_error(static_cast<TextPacket*>(argPacket)->text));
|
||||
break;
|
||||
|
||||
//errors
|
||||
default: {
|
||||
std::ostringstream msg;
|
||||
msg << "Unknown SerialPacketType encountered in World: " << static_cast<int>(argPacket->type);
|
||||
throw(std::runtime_error(msg.str()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "world.hpp"
|
||||
|
||||
#include "channels.hpp"
|
||||
|
||||
//-------------------------
|
||||
//map management
|
||||
//-------------------------
|
||||
|
||||
void World::SendRegionRequest(int roomIndex, int x, int y) {
|
||||
RegionPacket packet;
|
||||
|
||||
//pack the region's data
|
||||
packet.type = SerialPacketType::REGION_REQUEST;
|
||||
packet.roomIndex = roomIndex;
|
||||
packet.x = x;
|
||||
packet.y = y;
|
||||
|
||||
network.SendTo(Channels::SERVER, &packet);
|
||||
}
|
||||
|
||||
void World::hRegionContent(RegionPacket* const argPacket) {
|
||||
//replace existing regions
|
||||
regionPager.UnloadIf([&](Region const& region) -> bool {
|
||||
return region.GetX() == argPacket->x && region.GetY() == argPacket->y;
|
||||
});
|
||||
regionPager.PushRegion(argPacket->region);
|
||||
|
||||
//clean up after the serial code
|
||||
delete argPacket->region;
|
||||
argPacket->region = nullptr;
|
||||
}
|
||||
|
||||
void World::UpdateMap() {
|
||||
if (roomIndex == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
//these represent the zone of regions that the client needs loaded, including the mandatory buffers (+1/-1)
|
||||
int xStart = snapToBase(REGION_WIDTH, camera.x/tileSheet.GetTileW()) - REGION_WIDTH;
|
||||
int xEnd = snapToBase(REGION_WIDTH, (camera.x+camera.width)/tileSheet.GetTileW()) + REGION_WIDTH;
|
||||
|
||||
int yStart = snapToBase(REGION_HEIGHT, camera.y/tileSheet.GetTileH()) - REGION_HEIGHT;
|
||||
int yEnd = snapToBase(REGION_HEIGHT, (camera.y+camera.height)/tileSheet.GetTileH()) + REGION_HEIGHT;
|
||||
|
||||
//prune distant regions
|
||||
regionPager.GetContainer()->remove_if([&](Region const& region) -> bool {
|
||||
return region.GetX() < xStart || region.GetX() > xEnd || region.GetY() < yStart || region.GetY() > yEnd;
|
||||
});
|
||||
|
||||
//request empty regions within this zone
|
||||
for (int i = xStart; i <= xEnd; i += REGION_WIDTH) {
|
||||
for (int j = yStart; j <= yEnd; j += REGION_HEIGHT) {
|
||||
if (!regionPager.FindRegion(i, j)) {
|
||||
SendRegionRequest(roomIndex, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "world.hpp"
|
||||
|
||||
#include "channels.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
//-------------------------
|
||||
//monster management
|
||||
//-------------------------
|
||||
|
||||
void World::hMonsterCreate(MonsterPacket* const argPacket) {
|
||||
//check for logic errors
|
||||
if (monsterMap.find(argPacket->monsterIndex) != monsterMap.end()) {
|
||||
std::ostringstream msg;
|
||||
msg << "Double monster creation event; ";
|
||||
msg << "Index: " << argPacket->monsterIndex << "; ";
|
||||
msg << "Handle: " << argPacket->handle;
|
||||
throw(std::runtime_error(msg.str()));
|
||||
}
|
||||
|
||||
//ignore monsters from other rooms
|
||||
if (roomIndex != argPacket->roomIndex) {
|
||||
//temporary error checking
|
||||
std::ostringstream msg;
|
||||
msg << "Monster from the wrong room received: ";
|
||||
msg << "monsterIndex: " << argPacket->monsterIndex << ", roomIndex: " << argPacket->roomIndex;
|
||||
throw(std::runtime_error(msg.str()));
|
||||
}
|
||||
|
||||
//implicitly create the element
|
||||
BaseMonster* monster = &monsterMap[argPacket->monsterIndex];
|
||||
|
||||
//fill the monster's info
|
||||
monster->SetHandle(argPacket->handle);
|
||||
monster->SetAvatar(argPacket->avatar);
|
||||
monster->SetBounds(argPacket->bounds);
|
||||
monster->SetOrigin(argPacket->origin);
|
||||
monster->SetMotion(argPacket->motion);
|
||||
|
||||
//debug
|
||||
std::cout << "Monster Create, total: " << monsterMap.size() << std::endl;
|
||||
}
|
||||
|
||||
void World::hMonsterDelete(MonsterPacket* const argPacket) {
|
||||
//ignore if this monster doesn't exist
|
||||
std::map<int, BaseMonster>::iterator monsterIt = monsterMap.find(argPacket->monsterIndex);
|
||||
if (monsterIt == monsterMap.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//remove this monster
|
||||
monsterMap.erase(monsterIt);
|
||||
|
||||
//debug
|
||||
std::cout << "Monster Delete, total: " << monsterMap.size() << std::endl;
|
||||
}
|
||||
|
||||
void World::hQueryMonsterExists(MonsterPacket* const argPacket) {
|
||||
//ignore monsters in a different room (sub-optimal)
|
||||
if (argPacket->roomIndex != roomIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
//implicitly create the element
|
||||
BaseMonster* monster = &monsterMap[argPacket->monsterIndex];
|
||||
|
||||
//fill the monster's info
|
||||
monster->SetHandle(argPacket->handle);
|
||||
monster->SetAvatar(argPacket->avatar);
|
||||
monster->SetBounds(argPacket->bounds);
|
||||
monster->SetOrigin(argPacket->origin);
|
||||
monster->SetMotion(argPacket->motion);
|
||||
|
||||
//debug
|
||||
std::cout << "Monster Query, total: " << monsterMap.size() << std::endl;
|
||||
}
|
||||
|
||||
void World::hQueryMonsterStats(MonsterPacket* const argPacket) {
|
||||
//TODO: (9) World::hQueryMonsterStats()
|
||||
}
|
||||
|
||||
void World::hQueryMonsterLocation(MonsterPacket* const argPacket) {
|
||||
//TODO: (9) World::hQueryMonsterLocation()
|
||||
}
|
||||
|
||||
void World::hMonsterMovement(MonsterPacket* const argPacket) {
|
||||
//ignore if this monster doesn't exist
|
||||
std::map<int, BaseMonster>::iterator monsterIt = monsterMap.find(argPacket->monsterIndex);
|
||||
if (monsterIt == monsterMap.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
monsterIt->second.SetOrigin(argPacket->origin);
|
||||
monsterIt->second.SetOrigin(argPacket->motion);
|
||||
}
|
||||
|
||||
void World::hMonsterAttack(MonsterPacket* const argPacket) {
|
||||
//TODO: (9) World::hMonsterAttack()
|
||||
}
|
||||
|
||||
void World::hMonsterDamage(MonsterPacket* const argPacket) {
|
||||
//TODO: (9) World::hMonsterDamage()
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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_application.hpp"
|
||||
|
||||
//singletons
|
||||
#include "config_utility.hpp"
|
||||
#include "udp_network_utility.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
try {
|
||||
//create the singletons
|
||||
ConfigUtility::CreateSingleton();
|
||||
UDPNetworkUtility::CreateSingleton();
|
||||
|
||||
//call the client's routines
|
||||
ClientApplication::CreateSingleton();
|
||||
ClientApplication& app = ClientApplication::GetSingleton();
|
||||
|
||||
app.Init(argc, argv);
|
||||
app.Proc();
|
||||
app.Quit();
|
||||
|
||||
ClientApplication::DeleteSingleton();
|
||||
|
||||
//delete the singletons
|
||||
ConfigUtility::DeleteSingleton();
|
||||
UDPNetworkUtility::DeleteSingleton();
|
||||
}
|
||||
catch(exception& e) {
|
||||
cerr << "Fatal exception thrown: " << e.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
#include directories
|
||||
INCLUDES+=. client_utilities entities gameplay_scenes menu_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
|
||||
CXXSRC=$(wildcard *.cpp)
|
||||
|
||||
#objects
|
||||
OBJDIR=obj
|
||||
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
||||
|
||||
#output
|
||||
OUTDIR=../out
|
||||
OUT=$(addprefix $(OUTDIR)/,client)
|
||||
|
||||
#targets
|
||||
all: $(OBJ) $(OUT)
|
||||
$(MAKE) -C client_utilities
|
||||
$(MAKE) -C entities
|
||||
$(MAKE) -C gameplay_scenes
|
||||
$(MAKE) -C menu_scenes
|
||||
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
|
||||
|
||||
$(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
|
||||
@@ -1,116 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "disconnected_screen.hpp"
|
||||
|
||||
#include "channels.hpp"
|
||||
#include "config_utility.hpp"
|
||||
#include "udp_network_utility.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
//-------------------------
|
||||
//Public access members
|
||||
//-------------------------
|
||||
|
||||
DisconnectedScreen::DisconnectedScreen() {
|
||||
ConfigUtility& config = ConfigUtility::GetSingleton();
|
||||
|
||||
//setup the utility objects
|
||||
image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
|
||||
image.SetClipH(image.GetClipH()/3);
|
||||
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
|
||||
|
||||
//pass the utility objects
|
||||
backButton.SetImage(&image);
|
||||
backButton.SetFont(&font);
|
||||
|
||||
//set the button positions
|
||||
backButton.SetX(50);
|
||||
backButton.SetY(50 + image.GetClipH() * 0);
|
||||
|
||||
//set the button texts
|
||||
backButton.SetText("Back");
|
||||
|
||||
//full reset
|
||||
UDPNetworkUtility::GetSingleton().Unbind(Channels::SERVER);
|
||||
|
||||
//auto return
|
||||
startTick = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
DisconnectedScreen::~DisconnectedScreen() {
|
||||
//
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Frame loop
|
||||
//-------------------------
|
||||
|
||||
void DisconnectedScreen::Update() {
|
||||
if (std::chrono::steady_clock::now() - startTick > std::chrono::duration<int>(10)) {
|
||||
SetNextScene(SceneList::MAINMENU);
|
||||
}
|
||||
|
||||
//Eat incoming packets
|
||||
while(UDPNetworkUtility::GetSingleton().Receive());
|
||||
}
|
||||
|
||||
void DisconnectedScreen::Render(SDL_Surface* const screen) {
|
||||
ConfigUtility& config = ConfigUtility::GetSingleton();
|
||||
|
||||
backButton.DrawTo(screen);
|
||||
font.DrawStringTo(config["client.disconnectMessage"], screen, 50, 30);
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Event handlers
|
||||
//-------------------------
|
||||
|
||||
void DisconnectedScreen::QuitEvent() {
|
||||
SetNextScene(SceneList::QUIT);
|
||||
}
|
||||
|
||||
void DisconnectedScreen::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
||||
backButton.MouseMotion(motion);
|
||||
}
|
||||
|
||||
void DisconnectedScreen::MouseButtonDown(SDL_MouseButtonEvent const& button) {
|
||||
backButton.MouseButtonDown(button);
|
||||
}
|
||||
|
||||
void DisconnectedScreen::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
||||
if (backButton.MouseButtonUp(button) == Button::State::HOVER) {
|
||||
SetNextScene(SceneList::MAINMENU);
|
||||
}
|
||||
}
|
||||
|
||||
void DisconnectedScreen::KeyDown(SDL_KeyboardEvent const& key) {
|
||||
switch(key.keysym.sym) {
|
||||
case SDLK_ESCAPE:
|
||||
SetNextScene(SceneList::MAINMENU);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DisconnectedScreen::KeyUp(SDL_KeyboardEvent const& key) {
|
||||
//
|
||||
}
|
||||
@@ -1,296 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "lobby_menu.hpp"
|
||||
|
||||
#include "channels.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
|
||||
//-------------------------
|
||||
//Public access members
|
||||
//-------------------------
|
||||
|
||||
LobbyMenu::LobbyMenu(int* const argClientIndex, int* const argAccountIndex):
|
||||
clientIndex(*argClientIndex),
|
||||
accountIndex(*argAccountIndex)
|
||||
{
|
||||
//preemptive reset
|
||||
clientIndex = -1;
|
||||
accountIndex = -1;
|
||||
|
||||
//setup the utility objects
|
||||
image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
|
||||
image.SetClipH(image.GetClipH()/3);
|
||||
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
|
||||
|
||||
//pass the utility objects
|
||||
search.SetImage(&image);
|
||||
search.SetFont(&font);
|
||||
join.SetImage(&image);
|
||||
join.SetFont(&font);
|
||||
back.SetImage(&image);
|
||||
back.SetFont(&font);
|
||||
|
||||
//set the button positions
|
||||
search.SetX(50);
|
||||
search.SetY(50 + image.GetClipH() * 0);
|
||||
join.SetX(50);
|
||||
join.SetY(50 + image.GetClipH() * 1);
|
||||
back.SetX(50);
|
||||
back.SetY(50 + image.GetClipH() * 2);
|
||||
|
||||
//set the button texts
|
||||
search.SetText("Search");
|
||||
join.SetText("Join");
|
||||
back.SetText("Back");
|
||||
|
||||
//set the server list's position
|
||||
listBox = {300, 50, 200, font.GetCharH()};
|
||||
|
||||
//Eat incoming packets
|
||||
while(network.Receive());
|
||||
|
||||
//Initial broadcast
|
||||
SendBroadcastRequest();
|
||||
}
|
||||
|
||||
LobbyMenu::~LobbyMenu() {
|
||||
//
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Frame loop
|
||||
//-------------------------
|
||||
|
||||
void LobbyMenu::FrameStart() {
|
||||
//
|
||||
}
|
||||
|
||||
void LobbyMenu::Update() {
|
||||
//suck in and process all waiting packets
|
||||
SerialPacket* packetBuffer = reinterpret_cast<SerialPacket*>(new char[MAX_PACKET_SIZE]);
|
||||
while(network.Receive(packetBuffer)) {
|
||||
HandlePacket(packetBuffer);
|
||||
}
|
||||
delete reinterpret_cast<char*>(packetBuffer);
|
||||
}
|
||||
|
||||
void LobbyMenu::FrameEnd() {
|
||||
//
|
||||
}
|
||||
|
||||
void LobbyMenu::Render(SDL_Surface* const screen) {
|
||||
//TODO: (2) I need a proper UI system for the entire client and the editor
|
||||
|
||||
//UI
|
||||
search.DrawTo(screen);
|
||||
join.DrawTo(screen);
|
||||
back.DrawTo(screen);
|
||||
|
||||
//TODO: (3) draw headers for the server list
|
||||
//TODO: (3) ping/delay displayed in the server list
|
||||
for (int i = 0; i < serverInfo.size(); i++) {
|
||||
//draw the selected server's highlight
|
||||
if (selection == &serverInfo[i]) {
|
||||
SDL_Rect r = {
|
||||
(Sint16)listBox.x, (Sint16)listBox.y,
|
||||
(Uint16)listBox.w, (Uint16)listBox.h
|
||||
};
|
||||
r.y += i * listBox.h;
|
||||
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 49, 150, 5));
|
||||
}
|
||||
|
||||
//draw the server name
|
||||
font.DrawStringTo(serverInfo[i].name, screen, listBox.x, listBox.y + i*listBox.h);
|
||||
|
||||
//draw the player count
|
||||
std::ostringstream msg;
|
||||
msg << serverInfo[i].playerCount;
|
||||
font.DrawStringTo(msg.str(), screen, listBox.x + listBox.w, listBox.y + i*listBox.h);
|
||||
|
||||
//compatible?
|
||||
if (!serverInfo[i].compatible) {
|
||||
font.DrawStringTo("?", screen, listBox.x - font.GetCharW(), listBox.y + i*listBox.h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Event handlers
|
||||
//-------------------------
|
||||
|
||||
void LobbyMenu::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
||||
search.MouseMotion(motion);
|
||||
join.MouseMotion(motion);
|
||||
back.MouseMotion(motion);
|
||||
}
|
||||
|
||||
void LobbyMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) {
|
||||
search.MouseButtonDown(button);
|
||||
join.MouseButtonDown(button);
|
||||
back.MouseButtonDown(button);
|
||||
}
|
||||
|
||||
void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
||||
if (search.MouseButtonUp(button) == Button::State::HOVER) {
|
||||
SendBroadcastRequest();
|
||||
}
|
||||
else if (join.MouseButtonUp(button) == Button::State::HOVER && selection != nullptr && selection->compatible) {
|
||||
SendJoinRequest();
|
||||
}
|
||||
else if (back.MouseButtonUp(button) == Button::State::HOVER) {
|
||||
SetNextScene(SceneList::MAINMENU);
|
||||
}
|
||||
|
||||
//has the user selected a server on the list?
|
||||
BoundingBox tmpBox = listBox;
|
||||
tmpBox.h *= serverInfo.size();
|
||||
if (tmpBox.CheckOverlap({button.x, button.y})) {
|
||||
selection = &serverInfo[(button.y - listBox.y)/listBox.h];
|
||||
}
|
||||
else {
|
||||
selection = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void LobbyMenu::KeyDown(SDL_KeyboardEvent const& key) {
|
||||
switch(key.keysym.sym) {
|
||||
case SDLK_ESCAPE:
|
||||
SetNextScene(SceneList::MAINMENU);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LobbyMenu::KeyUp(SDL_KeyboardEvent const& key) {
|
||||
//
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Network handlers
|
||||
//-------------------------
|
||||
|
||||
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: {
|
||||
std::ostringstream msg;
|
||||
msg << "Unknown SerialPacketType encountered in LobbyMenu: " << static_cast<int>(argPacket->type);
|
||||
throw(std::runtime_error( msg.str() ));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LobbyMenu::HandleBroadcastResponse(ServerPacket* const argPacket) {
|
||||
//extract the data
|
||||
ServerInformation server;
|
||||
server.address = argPacket->srcAddress;
|
||||
server.name = argPacket->name;
|
||||
server.playerCount = argPacket->playerCount;
|
||||
server.version = argPacket->version;
|
||||
|
||||
//Checking compatibility
|
||||
server.compatible = server.version == NETWORK_VERSION;
|
||||
|
||||
//push
|
||||
serverInfo.push_back(server);
|
||||
}
|
||||
|
||||
void LobbyMenu::HandleJoinResponse(ClientPacket* const argPacket) {
|
||||
//save the server's data
|
||||
clientIndex = argPacket->clientIndex;
|
||||
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::WORLD);
|
||||
}
|
||||
|
||||
void LobbyMenu::HandleJoinRejection(TextPacket* const argPacket) {
|
||||
//TODO: (9) LobbyMenu::HandleJoinRejection()
|
||||
}
|
||||
|
||||
void LobbyMenu::HandleLoginRejection(TextPacket* const argPacket) {
|
||||
//TODO: (9) LobbyMenu::HandleLoginRejection
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//server control
|
||||
//-------------------------
|
||||
|
||||
void LobbyMenu::SendBroadcastRequest() {
|
||||
//broadcast to the network, or a specific server
|
||||
ClientPacket packet;
|
||||
packet.type = SerialPacketType::BROADCAST_REQUEST;
|
||||
network.SendTo(config["server.host"].c_str(), config.Int("server.port"), &packet);
|
||||
|
||||
//reset the server list
|
||||
serverInfo.clear();
|
||||
selection = nullptr;
|
||||
}
|
||||
|
||||
void LobbyMenu::SendJoinRequest() {
|
||||
//pack the packet
|
||||
ClientPacket packet;
|
||||
packet.type = SerialPacketType::JOIN_REQUEST;
|
||||
|
||||
//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);
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 LOBBYMENU_HPP_
|
||||
#define LOBBYMENU_HPP_
|
||||
|
||||
//graphics & ui
|
||||
#include "image.hpp"
|
||||
#include "raster_font.hpp"
|
||||
#include "button.hpp"
|
||||
#include "bounding_box.hpp"
|
||||
|
||||
//utilities
|
||||
#include "config_utility.hpp"
|
||||
#include "udp_network_utility.hpp"
|
||||
#include "serial_packet.hpp"
|
||||
|
||||
//client
|
||||
#include "base_scene.hpp"
|
||||
|
||||
//STL
|
||||
#include <vector>
|
||||
|
||||
class LobbyMenu : public BaseScene {
|
||||
public:
|
||||
//Public access members
|
||||
LobbyMenu(int* const argClientIndex, int* const argAccountIndex);
|
||||
~LobbyMenu();
|
||||
|
||||
protected:
|
||||
//Frame loop
|
||||
void FrameStart();
|
||||
void Update();
|
||||
void FrameEnd();
|
||||
void Render(SDL_Surface* const);
|
||||
|
||||
//Event handlers
|
||||
void MouseMotion(SDL_MouseMotionEvent const&);
|
||||
void MouseButtonDown(SDL_MouseButtonEvent const&);
|
||||
void MouseButtonUp(SDL_MouseButtonEvent const&);
|
||||
void KeyDown(SDL_KeyboardEvent const&);
|
||||
void KeyUp(SDL_KeyboardEvent const&);
|
||||
|
||||
//Network handlers
|
||||
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();
|
||||
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
|
||||
int& clientIndex;
|
||||
int& accountIndex;
|
||||
|
||||
//members
|
||||
Image image;
|
||||
RasterFont font;
|
||||
Button search;
|
||||
Button join;
|
||||
Button back;
|
||||
|
||||
//server list
|
||||
struct ServerInformation {
|
||||
IPaddress address;
|
||||
std::string name;
|
||||
int playerCount;
|
||||
int version;
|
||||
bool compatible;
|
||||
};
|
||||
|
||||
std::vector<ServerInformation> serverInfo;
|
||||
|
||||
//NOTE: a terrible hack
|
||||
//I'd love a proper gui system for this
|
||||
BoundingBox listBox;
|
||||
ServerInformation* selection = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,37 +0,0 @@
|
||||
#config
|
||||
INCLUDES+=. .. ../../common/graphics ../../common/map ../../common/network ../../common/network/packet_types ../../common/ui ../../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)/,client.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
|
||||
@@ -1,45 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "timer.hpp"
|
||||
|
||||
Timer::Timer(): start(Timer::Clock::now()) {
|
||||
//
|
||||
}
|
||||
|
||||
Timer::Timer(std::string s): name(s), start(Timer::Clock::now()) {
|
||||
//
|
||||
}
|
||||
|
||||
void Timer::Start() {
|
||||
start = Clock::now();
|
||||
}
|
||||
|
||||
void Timer::Stop() {
|
||||
timeSpan = Clock::now() - start;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, Timer& t) {
|
||||
os << t.GetName() << ": ";
|
||||
os << std::chrono::duration_cast<std::chrono::microseconds>(t.GetTime()).count();
|
||||
os << "us";
|
||||
return os;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 CHARACTERDEFINES_HPP_
|
||||
#define CHARACTERDEFINES_HPP_
|
||||
|
||||
#include <cmath>
|
||||
|
||||
//the speeds that the characters move
|
||||
constexpr double CHARACTER_WALKING_SPEED = 2.24;
|
||||
constexpr double CHARACTER_WALKING_MOD = 1.0/sqrt(2.0);
|
||||
constexpr double CHARACTER_WALKING_NEGATIVE_MOD = 1.0 - CHARACTER_WALKING_MOD;
|
||||
|
||||
//the bounds for the character objects, mapped to the default sprites
|
||||
constexpr int CHARACTER_BOUNDS_X = 0;
|
||||
constexpr int CHARACTER_BOUNDS_Y = 16;
|
||||
constexpr int CHARACTER_BOUNDS_WIDTH = 32;
|
||||
constexpr int CHARACTER_BOUNDS_HEIGHT = 32;
|
||||
|
||||
//the character's sprite format
|
||||
constexpr int CHARACTER_CELLS_X = 4;
|
||||
constexpr int CHARACTER_CELLS_Y = 4;
|
||||
|
||||
#endif
|
||||
@@ -1,37 +0,0 @@
|
||||
#config
|
||||
INCLUDES+=. ../map
|
||||
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)/,libcommon.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
|
||||
@@ -1,13 +0,0 @@
|
||||
all:
|
||||
$(MAKE) -C debugging
|
||||
$(MAKE) -C gameplay
|
||||
$(MAKE) -C graphics
|
||||
$(MAKE) -C map
|
||||
$(MAKE) -C network
|
||||
$(MAKE) -C ui
|
||||
$(MAKE) -C utilities
|
||||
|
||||
clean:
|
||||
$(RM) *.o *.a *.exe
|
||||
|
||||
rebuild: clean all
|
||||
@@ -1,200 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "region_pager_lua.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
//DOCS: Load, Save and Create fail unless the lua function has been set
|
||||
//DOCS: UnloadIf and UnloadAll will still continue without the function set
|
||||
|
||||
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);
|
||||
|
||||
//check if this function is available
|
||||
if (lua_isnil(lua, -1)) {
|
||||
lua_pop(lua, 1);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//something to work on
|
||||
Region tmpRegion(x, y);
|
||||
lua_pushlightuserdata(lua, &tmpRegion);
|
||||
|
||||
//call the funtion, 1 arg, 1 return
|
||||
if (lua_pcall(lua, 1, 1, 0) != LUA_OK) {
|
||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
|
||||
}
|
||||
|
||||
//check the return value, success or failure
|
||||
if (lua_toboolean(lua, -1)) {
|
||||
lua_pop(lua, 1);
|
||||
regionList.push_front(tmpRegion);
|
||||
return ®ionList.front();
|
||||
}
|
||||
else {
|
||||
lua_pop(lua, 1);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//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);
|
||||
|
||||
//check if this function is available
|
||||
if (lua_isnil(lua, -1)) {
|
||||
lua_pop(lua, 1);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//find the specified region
|
||||
Region* ptr = FindRegion(x, y);
|
||||
if (!ptr) {
|
||||
lua_pop(lua, 1);
|
||||
return nullptr;
|
||||
}
|
||||
lua_pushlightuserdata(lua, ptr);
|
||||
|
||||
//call the function, 1 arg, 1 return
|
||||
if (lua_pcall(lua, 1, 1, 0) != LUA_OK) {
|
||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
|
||||
}
|
||||
|
||||
//check the return value, success or failure
|
||||
if (lua_toboolean(lua, -1)) {
|
||||
lua_pop(lua, 1);
|
||||
return ptr;
|
||||
}
|
||||
else {
|
||||
lua_pop(lua, 1);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//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"));
|
||||
}
|
||||
|
||||
//get the pager's function from the registry
|
||||
lua_rawgeti(lua, LUA_REGISTRYINDEX, createRef);
|
||||
|
||||
//check if this function is available
|
||||
if (lua_isnil(lua, -1)) {
|
||||
lua_pop(lua, 1);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//something to work on
|
||||
Region tmpRegion(x, y);
|
||||
lua_pushlightuserdata(lua, &tmpRegion);
|
||||
|
||||
//call the function, 1 arg, 0 return
|
||||
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) {
|
||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
|
||||
}
|
||||
|
||||
//return the new region
|
||||
regionList.push_front(tmpRegion);
|
||||
return ®ionList.front();
|
||||
}
|
||||
|
||||
//no return
|
||||
void RegionPagerLua::UnloadIf(std::function<bool(Region const&)> fn) {
|
||||
//get the pager's function from the registry
|
||||
lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef);
|
||||
|
||||
//check if this function is available
|
||||
if (lua_isnil(lua, -1)) {
|
||||
lua_pop(lua, 1);
|
||||
//remove the regions anyway
|
||||
regionList.remove_if(fn);
|
||||
return;
|
||||
}
|
||||
|
||||
//run each region through this lambda
|
||||
regionList.remove_if([&](Region& region) -> bool {
|
||||
if (fn(region)) {
|
||||
|
||||
//push a copy of the function onto the stack with the region
|
||||
lua_pushvalue(lua, -1);
|
||||
lua_pushlightuserdata(lua, static_cast<void*>(®ion));
|
||||
|
||||
//call the function, 1 arg, 0 return
|
||||
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) {
|
||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
|
||||
}
|
||||
|
||||
//signal to the container
|
||||
return true;
|
||||
}
|
||||
//signal to the container
|
||||
return false;
|
||||
});
|
||||
|
||||
//pop the base copy of the function
|
||||
lua_pop(lua, 1);
|
||||
}
|
||||
|
||||
void RegionPagerLua::UnloadAll() {
|
||||
//get the pager's function from the registry
|
||||
lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef);
|
||||
|
||||
//check if this function is available
|
||||
if (lua_isnil(lua, -1)) {
|
||||
lua_pop(lua, 1);
|
||||
//remove the regions anyway
|
||||
regionList.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& it : regionList) {
|
||||
//push a copy of the function onto the stack with the region
|
||||
lua_pushvalue(lua, -1);
|
||||
lua_pushlightuserdata(lua, &it);
|
||||
|
||||
//call the function, 1 arg, 0 return
|
||||
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) {
|
||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
|
||||
}
|
||||
}
|
||||
|
||||
//pop the base copy of the function
|
||||
lua_pop(lua, 1);
|
||||
|
||||
//remove from memory
|
||||
regionList.clear();
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
#config
|
||||
INCLUDES+=. packet_types ../gameplay ../map ../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)/,libcommon.a)
|
||||
|
||||
#targets
|
||||
all: $(OBJ) $(OUT)
|
||||
ar -crs $(OUT) $(OBJ)
|
||||
$(MAKE) -C packet_types
|
||||
|
||||
$(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
|
||||
@@ -1,80 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "character_packet.hpp"
|
||||
|
||||
#include "serial_utility.hpp"
|
||||
|
||||
void serializeCharacter(void* buffer, CharacterPacket* packet) {
|
||||
serialCopy(&buffer, &packet->type, sizeof(SerialPacketType));
|
||||
|
||||
//identify the character
|
||||
serialCopy(&buffer, &packet->characterIndex, sizeof(int));
|
||||
serialCopy(&buffer, packet->handle, PACKET_STRING_SIZE);
|
||||
serialCopy(&buffer, packet->avatar, PACKET_STRING_SIZE);
|
||||
|
||||
//the owner
|
||||
serialCopy(&buffer, &packet->accountIndex, sizeof(int));
|
||||
|
||||
//location
|
||||
serialCopy(&buffer, &packet->roomIndex, sizeof(int));
|
||||
|
||||
serialCopy(&buffer, &packet->origin.x, sizeof(double));
|
||||
serialCopy(&buffer, &packet->origin.y, sizeof(double));
|
||||
|
||||
serialCopy(&buffer, &packet->motion.x, sizeof(double));
|
||||
serialCopy(&buffer, &packet->motion.y, sizeof(double));
|
||||
|
||||
serialCopy(&buffer, &packet->bounds.x, sizeof(int));
|
||||
serialCopy(&buffer, &packet->bounds.y, sizeof(int));
|
||||
serialCopy(&buffer, &packet->bounds.w, sizeof(int));
|
||||
serialCopy(&buffer, &packet->bounds.h, sizeof(int));
|
||||
|
||||
//gameplay components: equipment, items, buffs, debuffs...
|
||||
}
|
||||
|
||||
void deserializeCharacter(void* buffer, CharacterPacket* packet) {
|
||||
deserialCopy(&buffer, &packet->type, sizeof(SerialPacketType));
|
||||
|
||||
//identify the character
|
||||
deserialCopy(&buffer, &packet->characterIndex, sizeof(int));
|
||||
deserialCopy(&buffer, packet->handle, PACKET_STRING_SIZE);
|
||||
deserialCopy(&buffer, packet->avatar, PACKET_STRING_SIZE);
|
||||
|
||||
//the owner
|
||||
deserialCopy(&buffer, &packet->accountIndex, sizeof(int));
|
||||
|
||||
//location
|
||||
deserialCopy(&buffer, &packet->roomIndex, sizeof(int));
|
||||
|
||||
deserialCopy(&buffer, &packet->origin.x, sizeof(double));
|
||||
deserialCopy(&buffer, &packet->origin.y, sizeof(double));
|
||||
|
||||
deserialCopy(&buffer, &packet->motion.x, sizeof(double));
|
||||
deserialCopy(&buffer, &packet->motion.y, sizeof(double));
|
||||
|
||||
deserialCopy(&buffer, &packet->bounds.x, sizeof(int));
|
||||
deserialCopy(&buffer, &packet->bounds.y, sizeof(int));
|
||||
deserialCopy(&buffer, &packet->bounds.w, sizeof(int));
|
||||
deserialCopy(&buffer, &packet->bounds.h, sizeof(int));
|
||||
|
||||
//gameplay components: equipment, items, buffs, debuffs...
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 CHARACTERPACKET_HPP_
|
||||
#define CHARACTERPACKET_HPP_
|
||||
|
||||
#include "serial_packet_base.hpp"
|
||||
|
||||
#include "bounding_box.hpp"
|
||||
#include "vector2.hpp"
|
||||
|
||||
struct CharacterPacket : SerialPacketBase {
|
||||
//identify the character
|
||||
int characterIndex;
|
||||
char handle[PACKET_STRING_SIZE];
|
||||
char avatar[PACKET_STRING_SIZE];
|
||||
|
||||
//the owner
|
||||
int accountIndex;
|
||||
|
||||
//location
|
||||
int roomIndex;
|
||||
Vector2 origin;
|
||||
Vector2 motion;
|
||||
BoundingBox bounds;
|
||||
};
|
||||
|
||||
void serializeCharacter(void* buffer, CharacterPacket* packet);
|
||||
void deserializeCharacter(void* buffer, CharacterPacket* packet);
|
||||
|
||||
#endif
|
||||
@@ -1,40 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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_packet.hpp"
|
||||
|
||||
#include "serial_utility.hpp"
|
||||
|
||||
void serializeClient(void* buffer, ClientPacket* packet) {
|
||||
serialCopy(&buffer, &packet->type, sizeof(SerialPacketType));
|
||||
|
||||
serialCopy(&buffer, &packet->clientIndex, sizeof(int));
|
||||
serialCopy(&buffer, &packet->accountIndex, sizeof(int));
|
||||
serialCopy(&buffer, packet->username, PACKET_STRING_SIZE);
|
||||
}
|
||||
|
||||
void deserializeClient(void* buffer, ClientPacket* packet) {
|
||||
deserialCopy(&buffer, &packet->type, sizeof(SerialPacketType));
|
||||
|
||||
deserialCopy(&buffer, &packet->clientIndex, sizeof(int));
|
||||
deserialCopy(&buffer, &packet->accountIndex, sizeof(int));
|
||||
deserialCopy(&buffer, packet->username, PACKET_STRING_SIZE);
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 CLIENTPACKET_HPP_
|
||||
#define CLIENTPACKET_HPP_
|
||||
|
||||
#include "serial_packet_base.hpp"
|
||||
|
||||
struct ClientPacket : SerialPacketBase {
|
||||
int clientIndex;
|
||||
int accountIndex;
|
||||
char username[PACKET_STRING_SIZE];
|
||||
//TODO: (3) password, auth token
|
||||
};
|
||||
|
||||
void serializeClient(void* buffer, ClientPacket* packet);
|
||||
void deserializeClient(void* buffer, ClientPacket* packet);
|
||||
|
||||
#endif
|
||||
@@ -1,37 +0,0 @@
|
||||
#config
|
||||
INCLUDES+=. .. ../../gameplay ../../map ../../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)/,libcommon.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
|
||||
@@ -1,70 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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_packet.hpp"
|
||||
|
||||
#include "serial_utility.hpp"
|
||||
|
||||
void serializeMonster(void* buffer, MonsterPacket* packet) {
|
||||
serialCopy(&buffer, &packet->type, sizeof(SerialPacketType));
|
||||
|
||||
//identify the monster
|
||||
serialCopy(&buffer, &packet->monsterIndex, sizeof(int));
|
||||
serialCopy(&buffer, packet->handle, PACKET_STRING_SIZE);
|
||||
serialCopy(&buffer, packet->avatar, PACKET_STRING_SIZE);
|
||||
|
||||
//bounds
|
||||
serialCopy(&buffer, &packet->bounds.x, sizeof(int));
|
||||
serialCopy(&buffer, &packet->bounds.y, sizeof(int));
|
||||
serialCopy(&buffer, &packet->bounds.w, sizeof(int));
|
||||
serialCopy(&buffer, &packet->bounds.h, sizeof(int));
|
||||
|
||||
|
||||
//location
|
||||
serialCopy(&buffer, &packet->roomIndex, sizeof(int));
|
||||
serialCopy(&buffer, &packet->origin.x, sizeof(double));
|
||||
serialCopy(&buffer, &packet->origin.y, sizeof(double));
|
||||
serialCopy(&buffer, &packet->motion.x, sizeof(double));
|
||||
serialCopy(&buffer, &packet->motion.y, sizeof(double));
|
||||
}
|
||||
|
||||
void deserializeMonster(void* buffer, MonsterPacket* packet) {
|
||||
deserialCopy(&buffer, &packet->type, sizeof(SerialPacketType));
|
||||
|
||||
//identify the monster
|
||||
deserialCopy(&buffer, &packet->monsterIndex, sizeof(int));
|
||||
deserialCopy(&buffer, packet->handle, PACKET_STRING_SIZE);
|
||||
deserialCopy(&buffer, packet->avatar, PACKET_STRING_SIZE);
|
||||
|
||||
//bounds
|
||||
deserialCopy(&buffer, &packet->bounds.x, sizeof(int));
|
||||
deserialCopy(&buffer, &packet->bounds.y, sizeof(int));
|
||||
deserialCopy(&buffer, &packet->bounds.w, sizeof(int));
|
||||
deserialCopy(&buffer, &packet->bounds.h, sizeof(int));
|
||||
|
||||
|
||||
//location
|
||||
deserialCopy(&buffer, &packet->roomIndex, sizeof(int));
|
||||
deserialCopy(&buffer, &packet->origin.x, sizeof(double));
|
||||
deserialCopy(&buffer, &packet->origin.y, sizeof(double));
|
||||
deserialCopy(&buffer, &packet->motion.x, sizeof(double));
|
||||
deserialCopy(&buffer, &packet->motion.y, sizeof(double));
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 MONSTERPACKET_HPP_
|
||||
#define MONSTERPACKET_HPP_
|
||||
|
||||
#include "serial_packet_base.hpp"
|
||||
|
||||
#include "bounding_box.hpp"
|
||||
#include "vector2.hpp"
|
||||
|
||||
struct MonsterPacket : SerialPacketBase {
|
||||
//identify the monster
|
||||
int monsterIndex;
|
||||
char handle[PACKET_STRING_SIZE];
|
||||
char avatar[PACKET_STRING_SIZE];
|
||||
BoundingBox bounds;
|
||||
|
||||
//location
|
||||
int roomIndex;
|
||||
Vector2 origin;
|
||||
Vector2 motion;
|
||||
};
|
||||
|
||||
void serializeMonster(void* buffer, MonsterPacket* packet);
|
||||
void deserializeMonster(void* buffer, MonsterPacket* packet);
|
||||
|
||||
#endif
|
||||
@@ -1,79 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "region_packet.hpp"
|
||||
|
||||
#include "serial_utility.hpp"
|
||||
|
||||
void serializeRegion(void* buffer, RegionPacket* packet) {
|
||||
serialCopy(&buffer, &packet->type, sizeof(SerialPacketType));
|
||||
|
||||
//format
|
||||
serialCopy(&buffer, &packet->roomIndex, sizeof(int));
|
||||
serialCopy(&buffer, &packet->x, sizeof(int));
|
||||
serialCopy(&buffer, &packet->y, sizeof(int));
|
||||
|
||||
if (packet->type != SerialPacketType::REGION_CONTENT) {
|
||||
return;
|
||||
}
|
||||
|
||||
//tiles
|
||||
for (int i = 0; i < REGION_WIDTH; i++) {
|
||||
for (int j = 0; j < REGION_HEIGHT; j++) {
|
||||
for (int k = 0; k < REGION_DEPTH; k++) {
|
||||
*reinterpret_cast<Region::type_t*>(buffer) = packet->region->GetTile(i, j, k);
|
||||
buffer = reinterpret_cast<char*>(buffer) + sizeof(Region::type_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//solids
|
||||
serialCopy(&buffer, packet->region->GetSolidBitset(), REGION_SOLID_FOOTPRINT);
|
||||
}
|
||||
|
||||
void deserializeRegion(void* buffer, RegionPacket* packet) {
|
||||
deserialCopy(&buffer, &packet->type, sizeof(SerialPacketType));
|
||||
|
||||
//format
|
||||
deserialCopy(&buffer, &packet->roomIndex, sizeof(int));
|
||||
deserialCopy(&buffer, &packet->x, sizeof(int));
|
||||
deserialCopy(&buffer, &packet->y, sizeof(int));
|
||||
|
||||
if (packet->type != SerialPacketType::REGION_CONTENT) {
|
||||
return;
|
||||
}
|
||||
|
||||
//an object to work on
|
||||
packet->region = new Region(packet->x, packet->y);
|
||||
|
||||
//tiles
|
||||
for (int i = 0; i < REGION_WIDTH; i++) {
|
||||
for (int j = 0; j < REGION_HEIGHT; j++) {
|
||||
for (int k = 0; k < REGION_DEPTH; k++) {
|
||||
packet->region->SetTile(i, j, k, *reinterpret_cast<Region::type_t*>(buffer));
|
||||
buffer = reinterpret_cast<char*>(buffer) + sizeof(Region::type_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//solids
|
||||
deserialCopy(&buffer, packet->region->GetSolidBitset(), REGION_SOLID_FOOTPRINT);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 REGIONPACKET_HPP_
|
||||
#define REGIONPACKET_HPP_
|
||||
|
||||
#include "serial_packet_base.hpp"
|
||||
|
||||
#include "region.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
//define the memory footprint for the region's members
|
||||
constexpr int REGION_TILE_FOOTPRINT = sizeof(Region::type_t) * REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH;
|
||||
constexpr int REGION_SOLID_FOOTPRINT = ceil(REGION_WIDTH * REGION_HEIGHT / 8.0);
|
||||
constexpr int REGION_METADATA_FOOTPRINT = sizeof(int) * 3;
|
||||
|
||||
struct RegionPacket : SerialPacketBase {
|
||||
//location/identify the region
|
||||
int roomIndex;
|
||||
int x, y;
|
||||
|
||||
//the data
|
||||
Region* region;
|
||||
};
|
||||
|
||||
void serializeRegion(void* buffer, RegionPacket* packet);
|
||||
void deserializeRegion(void* buffer, RegionPacket* packet);
|
||||
|
||||
#endif
|
||||
@@ -1,24 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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_packet_base.hpp"
|
||||
|
||||
//sanity check
|
||||
@@ -1,39 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 SERIALPACKETBASE_HPP_
|
||||
#define SERIALPACKETBASE_HPP_
|
||||
|
||||
#include "serial_packet_type.hpp"
|
||||
|
||||
#include "SDL/SDL_net.h"
|
||||
|
||||
constexpr int PACKET_STRING_SIZE = 100;
|
||||
|
||||
struct SerialPacketBase {
|
||||
//members
|
||||
SerialPacketType type;
|
||||
IPaddress srcAddress;
|
||||
|
||||
virtual ~SerialPacketBase() {};
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,42 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#include "server_packet.hpp"
|
||||
|
||||
#include "serial_utility.hpp"
|
||||
|
||||
void serializeServer(void* buffer, ServerPacket* packet) {
|
||||
serialCopy(&buffer, &packet->type, sizeof(SerialPacketType));
|
||||
|
||||
//identify the server
|
||||
serialCopy(&buffer, packet->name, PACKET_STRING_SIZE);
|
||||
serialCopy(&buffer, &packet->playerCount, sizeof(int));
|
||||
serialCopy(&buffer, &packet->version, sizeof(int));
|
||||
}
|
||||
|
||||
void deserializeServer(void* buffer, ServerPacket* packet) {
|
||||
deserialCopy(&buffer, &packet->type, sizeof(SerialPacketType));
|
||||
|
||||
//identify the server
|
||||
deserialCopy(&buffer, packet->name, PACKET_STRING_SIZE);
|
||||
deserialCopy(&buffer, &packet->playerCount, sizeof(int));
|
||||
deserialCopy(&buffer, &packet->version, sizeof(int));
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 SERVERPACKET_HPP_
|
||||
#define SERVERPACKET_HPP_
|
||||
|
||||
#include "serial_packet_base.hpp"
|
||||
|
||||
struct ServerPacket : SerialPacketBase {
|
||||
//identify the server
|
||||
char name[PACKET_STRING_SIZE];
|
||||
int playerCount;
|
||||
int version;
|
||||
};
|
||||
|
||||
void serializeServer(void* buffer, ServerPacket* packet);
|
||||
void deserializeServer(void* buffer, ServerPacket* packet);
|
||||
|
||||
#endif
|
||||
@@ -1,52 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "text_packet.hpp"
|
||||
|
||||
#include "serial_utility.hpp"
|
||||
|
||||
void serializeText(void* buffer, TextPacket* packet) {
|
||||
serialCopy(&buffer, &packet->type, sizeof(SerialPacketType));
|
||||
|
||||
//content
|
||||
serialCopy(&buffer, packet->name, PACKET_STRING_SIZE);
|
||||
serialCopy(&buffer, packet->text, PACKET_STRING_SIZE);
|
||||
|
||||
//location
|
||||
serialCopy(&buffer, &packet->roomIndex, sizeof(int));
|
||||
serialCopy(&buffer, &packet->origin.x, sizeof(double));
|
||||
serialCopy(&buffer, &packet->origin.y, sizeof(double));
|
||||
serialCopy(&buffer, &packet->range, sizeof(int));
|
||||
}
|
||||
|
||||
void deserializeText(void* buffer, TextPacket* packet) {
|
||||
deserialCopy(&buffer, &packet->type, sizeof(SerialPacketType));
|
||||
|
||||
//content
|
||||
deserialCopy(&buffer, packet->name, PACKET_STRING_SIZE);
|
||||
deserialCopy(&buffer, packet->text, PACKET_STRING_SIZE);
|
||||
|
||||
//location
|
||||
deserialCopy(&buffer, &packet->roomIndex, sizeof(int));
|
||||
deserialCopy(&buffer, &packet->origin.x, sizeof(double));
|
||||
deserialCopy(&buffer, &packet->origin.y, sizeof(double));
|
||||
deserialCopy(&buffer, &packet->range, sizeof(int));
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 TEXTPACKET_HPP_
|
||||
#define TEXTPACKET_HPP_
|
||||
|
||||
#include "serial_packet_base.hpp"
|
||||
|
||||
#include "vector2.hpp"
|
||||
|
||||
struct TextPacket : SerialPacketBase {
|
||||
char name[PACKET_STRING_SIZE];
|
||||
char text[PACKET_STRING_SIZE];
|
||||
int roomIndex;
|
||||
Vector2 origin;
|
||||
int range;
|
||||
};
|
||||
|
||||
void serializeText(void* buffer, TextPacket* packet);
|
||||
void deserializeText(void* buffer, TextPacket* packet);
|
||||
|
||||
#endif
|
||||
@@ -1,66 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 SERIALPACKET_HPP_
|
||||
#define SERIALPACKET_HPP_
|
||||
|
||||
#include "serial_packet_base.hpp"
|
||||
#include "character_packet.hpp"
|
||||
#include "client_packet.hpp"
|
||||
#include "monster_packet.hpp"
|
||||
#include "region_packet.hpp"
|
||||
#include "server_packet.hpp"
|
||||
#include "text_packet.hpp"
|
||||
|
||||
//SerialPacketBase is defined in serial_packet_base.hpp
|
||||
typedef SerialPacketBase SerialPacket;
|
||||
|
||||
//DOCS: NETWORK_VERSION is used to discern compatible servers and clients
|
||||
constexpr int NETWORK_VERSION = 20150304;
|
||||
|
||||
union MaxPacket {
|
||||
CharacterPacket a;
|
||||
ClientPacket b;
|
||||
MonsterPacket c;
|
||||
RegionPacket d;
|
||||
ServerPacket e;
|
||||
TextPacket f;
|
||||
};
|
||||
|
||||
constexpr int MAX_PACKET_SIZE = sizeof(MaxPacket);
|
||||
|
||||
/* DOCS: PACKET_BUFFER_SIZE is the memory required to store serialized data
|
||||
* DOCS: SerialPacketType::REGION_CONTENT is currently the largest packet type
|
||||
* Serialized RegionPacket structure:
|
||||
* SerialPacketType
|
||||
* room index (int)
|
||||
* X & Y position (int)
|
||||
* tile data (3 layers)
|
||||
* solid data (bitset)
|
||||
*/
|
||||
|
||||
constexpr int PACKET_BUFFER_SIZE =
|
||||
sizeof(SerialPacketType) +
|
||||
REGION_METADATA_FOOTPRINT +
|
||||
REGION_TILE_FOOTPRINT +
|
||||
REGION_SOLID_FOOTPRINT;
|
||||
|
||||
#endif
|
||||
@@ -1,187 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 SERIALPACKETTYPE_HPP_
|
||||
#define SERIALPACKETTYPE_HPP_
|
||||
|
||||
/* DOCS: The headers indicate what packet type is used for each message
|
||||
* different messages under the same header will carry different amounts of
|
||||
* valid data, but it will still be carried in that packet's format.
|
||||
* FORMAT_* is for internal use, deviding the different format bounds.
|
||||
*/
|
||||
|
||||
enum class SerialPacketType {
|
||||
//default: there is something wrong
|
||||
NONE,
|
||||
|
||||
//-------------------------
|
||||
//ServerPacket
|
||||
// name, player count, version
|
||||
//-------------------------
|
||||
|
||||
FORMAT_SERVER,
|
||||
|
||||
//heartbeat
|
||||
PING,
|
||||
PONG,
|
||||
|
||||
//Used for finding available servers
|
||||
BROADCAST_REQUEST,
|
||||
BROADCAST_RESPONSE,
|
||||
|
||||
FORMAT_END_SERVER,
|
||||
|
||||
//-------------------------
|
||||
//ClientPacket
|
||||
// client index, account index, username
|
||||
//-------------------------
|
||||
|
||||
FORMAT_CLIENT,
|
||||
|
||||
//Connecting to a server as a client
|
||||
JOIN_REQUEST,
|
||||
JOIN_RESPONSE,
|
||||
|
||||
//disconnect from the server
|
||||
DISCONNECT_REQUEST,
|
||||
DISCONNECT_RESPONSE,
|
||||
ADMIN_DISCONNECT_FORCED,
|
||||
|
||||
//load the account
|
||||
LOGIN_REQUEST,
|
||||
LOGIN_RESPONSE,
|
||||
|
||||
//unload the account
|
||||
LOGOUT_REQUEST,
|
||||
LOGOUT_RESPONSE,
|
||||
|
||||
//shut down the server
|
||||
ADMIN_SHUTDOWN_REQUEST,
|
||||
|
||||
FORMAT_END_CLIENT,
|
||||
|
||||
//-------------------------
|
||||
//RegionPacket
|
||||
// room index, x, y, raw data
|
||||
//-------------------------
|
||||
|
||||
FORMAT_REGION,
|
||||
|
||||
//map data
|
||||
REGION_REQUEST,
|
||||
REGION_CONTENT,
|
||||
|
||||
FORMAT_END_REGION,
|
||||
|
||||
//-------------------------
|
||||
//CharacterPacket
|
||||
// character index,
|
||||
// handle, avatar,
|
||||
// account index (owner),
|
||||
// room index, origin, motion
|
||||
//-------------------------
|
||||
|
||||
FORMAT_CHARACTER,
|
||||
|
||||
//full data update
|
||||
CHARACTER_UPDATE,
|
||||
|
||||
//character management
|
||||
CHARACTER_CREATE,
|
||||
CHARACTER_DELETE,
|
||||
CHARACTER_LOAD,
|
||||
CHARACTER_UNLOAD,
|
||||
|
||||
//find out info from the server
|
||||
QUERY_CHARACTER_EXISTS,
|
||||
QUERY_CHARACTER_STATS,
|
||||
QUERY_CHARACTER_LOCATION,
|
||||
|
||||
//actions taken
|
||||
CHARACTER_MOVEMENT,
|
||||
CHARACTER_ATTACK,
|
||||
CHARACTER_DAMAGE,
|
||||
|
||||
//admin control
|
||||
// ADMIN_SET_CHARACTER_ORIGIN,
|
||||
|
||||
FORMAT_END_CHARACTER,
|
||||
|
||||
//-------------------------
|
||||
//MonsterPacket
|
||||
// monster index,
|
||||
// handle, avatar
|
||||
// bounds
|
||||
// room index, origin, motion
|
||||
//-------------------------
|
||||
|
||||
FORMAT_MONSTER,
|
||||
|
||||
//full data update
|
||||
MONSTER_UPDATE,
|
||||
|
||||
//character management
|
||||
MONSTER_CREATE,
|
||||
MONSTER_DELETE,
|
||||
|
||||
//find out info from the server
|
||||
QUERY_MONSTER_EXISTS,
|
||||
QUERY_MONSTER_STATS,
|
||||
QUERY_MONSTER_LOCATION,
|
||||
|
||||
//actions taken
|
||||
MONSTER_MOVEMENT,
|
||||
MONSTER_ATTACK,
|
||||
MONSTER_DAMAGE,
|
||||
|
||||
FORMAT_END_MONSTER,
|
||||
|
||||
//-------------------------
|
||||
//TextPacket
|
||||
// name, text
|
||||
//-------------------------
|
||||
|
||||
FORMAT_TEXT,
|
||||
|
||||
//general speech
|
||||
TEXT_BROADCAST,
|
||||
TEXT_SPEECH,
|
||||
TEXT_WHISPER,
|
||||
|
||||
//rejection/error messages
|
||||
JOIN_REJECTION,
|
||||
LOGIN_REJECTION,
|
||||
REGION_REJECTION,
|
||||
CHARACTER_REJECTION,
|
||||
MONSTER_REJECTION,
|
||||
SHUTDOWN_REJECTION,
|
||||
QUERY_REJECTION,
|
||||
|
||||
FORMAT_END_TEXT,
|
||||
|
||||
//-------------------------
|
||||
//not used
|
||||
//-------------------------
|
||||
|
||||
LAST
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,105 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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_utility.hpp"
|
||||
|
||||
//packet types
|
||||
#include "character_packet.hpp"
|
||||
#include "client_packet.hpp"
|
||||
#include "monster_packet.hpp"
|
||||
#include "region_packet.hpp"
|
||||
#include "server_packet.hpp"
|
||||
#include "text_packet.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
//macros
|
||||
#define BOUNDS(type, lower, upper) ((type) > (lower) && (type) < (upper))
|
||||
|
||||
//raw memory copy
|
||||
void serialCopy(void** buffer, void* data, int size) {
|
||||
memcpy(*buffer, data, size);
|
||||
*buffer = reinterpret_cast<char*>(*buffer) + size;
|
||||
}
|
||||
|
||||
void deserialCopy(void** buffer, void* data, int size) {
|
||||
memcpy(data, *buffer, size);
|
||||
*buffer = reinterpret_cast<char*>(*buffer) + size;
|
||||
}
|
||||
|
||||
//DOCS: The server and client MUST use the correct packet types
|
||||
|
||||
//main switch functions
|
||||
void serializePacket(void* buffer, SerialPacketBase* packet) {
|
||||
if (BOUNDS(packet->type, SerialPacketType::FORMAT_SERVER, SerialPacketType::FORMAT_END_SERVER)) {
|
||||
serializeServer(buffer, static_cast<ServerPacket*>(packet));
|
||||
}
|
||||
|
||||
if (BOUNDS(packet->type, SerialPacketType::FORMAT_CLIENT, SerialPacketType::FORMAT_END_CLIENT)) {
|
||||
serializeClient(buffer, static_cast<ClientPacket*>(packet));
|
||||
}
|
||||
|
||||
if (BOUNDS(packet->type, SerialPacketType::FORMAT_REGION, SerialPacketType::FORMAT_END_REGION)) {
|
||||
serializeRegion(buffer, static_cast<RegionPacket*>(packet));
|
||||
}
|
||||
|
||||
if (BOUNDS(packet->type, SerialPacketType::FORMAT_CHARACTER, SerialPacketType::FORMAT_END_CHARACTER)) {
|
||||
serializeCharacter(buffer, static_cast<CharacterPacket*>(packet));
|
||||
}
|
||||
|
||||
if (BOUNDS(packet->type, SerialPacketType::FORMAT_MONSTER, SerialPacketType::FORMAT_END_MONSTER)) {
|
||||
serializeMonster(buffer, static_cast<MonsterPacket*>(packet));
|
||||
}
|
||||
|
||||
if (BOUNDS(packet->type, SerialPacketType::FORMAT_TEXT, SerialPacketType::FORMAT_END_TEXT)) {
|
||||
serializeText(buffer, static_cast<TextPacket*>(packet));
|
||||
}
|
||||
}
|
||||
|
||||
void deserializePacket(void* buffer, SerialPacketBase* packet) {
|
||||
//find the type, so that you can actually deserialize the packet!
|
||||
SerialPacketType type;
|
||||
memcpy(&type, buffer, sizeof(SerialPacketType));
|
||||
|
||||
if (BOUNDS(type, SerialPacketType::FORMAT_SERVER, SerialPacketType::FORMAT_END_SERVER)) {
|
||||
deserializeServer(buffer, static_cast<ServerPacket*>(packet));
|
||||
}
|
||||
|
||||
if (BOUNDS(type, SerialPacketType::FORMAT_CLIENT, SerialPacketType::FORMAT_END_CLIENT)) {
|
||||
deserializeClient(buffer, static_cast<ClientPacket*>(packet));
|
||||
}
|
||||
|
||||
if (BOUNDS(type, SerialPacketType::FORMAT_REGION, SerialPacketType::FORMAT_END_REGION)) {
|
||||
deserializeRegion(buffer, static_cast<RegionPacket*>(packet));
|
||||
}
|
||||
|
||||
if (BOUNDS(type, SerialPacketType::FORMAT_CHARACTER, SerialPacketType::FORMAT_END_CHARACTER)) {
|
||||
deserializeCharacter(buffer, static_cast<CharacterPacket*>(packet));
|
||||
}
|
||||
|
||||
if (BOUNDS(type, SerialPacketType::FORMAT_MONSTER, SerialPacketType::FORMAT_END_MONSTER)) {
|
||||
deserializeMonster(buffer, static_cast<MonsterPacket*>(packet));
|
||||
}
|
||||
|
||||
if (BOUNDS(type, SerialPacketType::FORMAT_TEXT, SerialPacketType::FORMAT_END_TEXT)) {
|
||||
deserializeText(buffer, static_cast<TextPacket*>(packet));
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 SERIALIZEUTILITY_HPP_
|
||||
#define SERIALIZEUTILITY_HPP_
|
||||
|
||||
#include "serial_packet_base.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
//raw memory copy
|
||||
void serialCopy(void** buffer, void* data, int size);
|
||||
void deserialCopy(void** buffer, void* data, int size);
|
||||
|
||||
//primary functions
|
||||
void serializePacket(void* buffer, SerialPacketBase* packet);
|
||||
void deserializePacket(void* buffer, SerialPacketBase* packet);
|
||||
|
||||
#endif
|
||||
@@ -1,224 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "udp_network_utility.hpp"
|
||||
|
||||
#include "serial_packet.hpp"
|
||||
#include "serial_utility.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
//DOCS: memset() is used before sending a packet to remove old data; you don't want to send sensitive data over the network
|
||||
//NOTE: don't confuse SerialPacketBase with UDPpacket
|
||||
|
||||
void UDPNetworkUtility::Open(int port) {
|
||||
socket = SDLNet_UDP_Open(port);
|
||||
packet = SDLNet_AllocPacket(PACKET_BUFFER_SIZE);
|
||||
if (!socket || !packet) {
|
||||
Close();
|
||||
throw(std::runtime_error("Failed to open UDPNetworkUtility"));
|
||||
}
|
||||
}
|
||||
|
||||
void UDPNetworkUtility::Close() {
|
||||
SDLNet_UDP_Close(socket);
|
||||
SDLNet_FreePacket(packet);
|
||||
socket = nullptr;
|
||||
packet = nullptr;
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//bind to a channel
|
||||
//-------------------------
|
||||
|
||||
int UDPNetworkUtility::Bind(const char* ip, int port, int channel) {
|
||||
IPaddress add;
|
||||
if (SDLNet_ResolveHost(&add, ip, port) == -1) {
|
||||
throw(std::runtime_error("Failed to resolve a host"));
|
||||
}
|
||||
|
||||
return Bind(add, channel);
|
||||
}
|
||||
|
||||
int UDPNetworkUtility::Bind(IPaddress add, int channel) {
|
||||
int ret = SDLNet_UDP_Bind(socket, channel, &add);
|
||||
|
||||
if (ret < 0) {
|
||||
throw(std::runtime_error("Failed to bind to a channel"));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void UDPNetworkUtility::Unbind(int channel) {
|
||||
SDLNet_UDP_Unbind(socket, channel);
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//send a buffer
|
||||
//-------------------------
|
||||
|
||||
int UDPNetworkUtility::SendTo(const char* ip, int port, void* data, int len) {
|
||||
IPaddress add;
|
||||
if (SDLNet_ResolveHost(&add, ip, port) == -1) {
|
||||
throw(std::runtime_error("Failed to resolve a host"));
|
||||
}
|
||||
|
||||
SendTo(add, data, len);
|
||||
}
|
||||
|
||||
int UDPNetworkUtility::SendTo(IPaddress add, void* data, int len) {
|
||||
if (len > packet->maxlen) {
|
||||
throw(std::runtime_error("The buffer is to large for the UDPpacket"));
|
||||
}
|
||||
memset(packet->data, 0, packet->maxlen);
|
||||
memcpy(packet->data, data, len);
|
||||
packet->len = len;
|
||||
packet->address = add;
|
||||
|
||||
int ret = SDLNet_UDP_Send(socket, -1, packet);
|
||||
|
||||
if (ret <= 0) {
|
||||
throw(std::runtime_error("Failed to send a packet"));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int UDPNetworkUtility::SendTo(int channel, void* data, int len) {
|
||||
if (len > packet->maxlen) {
|
||||
throw(std::runtime_error("The buffer is to large for the UDPpacket"));
|
||||
}
|
||||
memset(packet->data, 0, packet->maxlen);
|
||||
memcpy(packet->data, data, len);
|
||||
packet->len = len;
|
||||
|
||||
int ret = SDLNet_UDP_Send(socket, channel, packet);
|
||||
|
||||
if (ret <= 0) {
|
||||
throw(std::runtime_error("Failed to send a packet"));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int UDPNetworkUtility::SendToAllChannels(void* data, int len) {
|
||||
if (len > packet->maxlen) {
|
||||
throw(std::runtime_error("The buffer is to large for the UDPpacket"));
|
||||
}
|
||||
memset(packet->data, 0, packet->maxlen);
|
||||
memcpy(packet->data, data, len);
|
||||
packet->len = len;
|
||||
|
||||
int sent = 0;
|
||||
|
||||
//send to all bound channels
|
||||
for (int i = 0; i < SDLNET_MAX_UDPCHANNELS; i++) {
|
||||
if (SDLNet_UDP_GetPeerAddress(socket, i)) {
|
||||
sent += SDLNet_UDP_Send(socket, i, packet);
|
||||
}
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
int UDPNetworkUtility::Receive() {
|
||||
memset(packet->data, 0, packet->maxlen);
|
||||
int ret = SDLNet_UDP_Recv(socket, packet);
|
||||
|
||||
if (ret < 0) {
|
||||
throw(std::runtime_error("Unknown network error occured"));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//send a SerialPacketBase
|
||||
//-------------------------
|
||||
|
||||
int UDPNetworkUtility::SendTo(const char* ip, int port, SerialPacketBase* serialPacket) {
|
||||
IPaddress add;
|
||||
if (SDLNet_ResolveHost(&add, ip, port) == -1) {
|
||||
throw(std::runtime_error("Failed to resolve a host"));
|
||||
}
|
||||
|
||||
SendTo(add, serialPacket);
|
||||
}
|
||||
|
||||
int UDPNetworkUtility::SendTo(IPaddress add, SerialPacketBase* serialPacket) {
|
||||
memset(packet->data, 0, packet->maxlen);
|
||||
serializePacket(packet->data, serialPacket);
|
||||
packet->len = PACKET_BUFFER_SIZE;
|
||||
packet->address = add;
|
||||
|
||||
int ret = SDLNet_UDP_Send(socket, -1, packet);
|
||||
|
||||
if (ret <= 0) {
|
||||
throw(std::runtime_error("Failed to send a packet"));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int UDPNetworkUtility::SendTo(int channel, SerialPacketBase* serialPacket) {
|
||||
memset(packet->data, 0, packet->maxlen);
|
||||
serializePacket(packet->data, serialPacket);
|
||||
packet->len = PACKET_BUFFER_SIZE;
|
||||
|
||||
int ret = SDLNet_UDP_Send(socket, channel, packet);
|
||||
|
||||
if (ret <= 0) {
|
||||
throw(std::runtime_error("Failed to send a packet"));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int UDPNetworkUtility::SendToAllChannels(SerialPacketBase* serialPacket) {
|
||||
memset(packet->data, 0, packet->maxlen);
|
||||
serializePacket(packet->data, serialPacket);
|
||||
packet->len = PACKET_BUFFER_SIZE;
|
||||
|
||||
int sent = 0;
|
||||
|
||||
//send to all bound channels
|
||||
for (int i = 0; i < SDLNET_MAX_UDPCHANNELS; i++) {
|
||||
if (SDLNet_UDP_GetPeerAddress(socket, i)) {
|
||||
sent += SDLNet_UDP_Send(socket, i, packet);
|
||||
}
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
int UDPNetworkUtility::Receive(SerialPacketBase* serialPacket) {
|
||||
memset(packet->data, 0, packet->maxlen);
|
||||
int ret = SDLNet_UDP_Recv(socket, packet);
|
||||
deserializePacket(packet->data, serialPacket);
|
||||
serialPacket->srcAddress = packet->address;
|
||||
|
||||
if (ret < 0) {
|
||||
throw(std::runtime_error("Unknown network error occured"));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 UDPNETWORKUTILITY_HPP_
|
||||
#define UDPNETWORKUTILITY_HPP_
|
||||
|
||||
//common
|
||||
#include "serial_packet_base.hpp"
|
||||
#include "singleton.hpp"
|
||||
|
||||
//APIs
|
||||
#include "SDL/SDL_net.h"
|
||||
|
||||
class UDPNetworkUtility : public Singleton<UDPNetworkUtility> {
|
||||
public:
|
||||
void Open(int port);
|
||||
void Close();
|
||||
|
||||
//bind to a channel
|
||||
int Bind(const char* ip, int port, int channel = -1);
|
||||
int Bind(IPaddress add, int channel = -1);
|
||||
void Unbind(int channel);
|
||||
|
||||
IPaddress* GetIPAddress(int channel) {
|
||||
return SDLNet_UDP_GetPeerAddress(socket, channel);
|
||||
}
|
||||
|
||||
//send a buffer
|
||||
int SendTo(const char* ip, int port, void* data, int len);
|
||||
int SendTo(IPaddress add, void* data, int len);
|
||||
int SendTo(int channel, void* data, int len);
|
||||
int SendToAllChannels(void* data, int len);
|
||||
int Receive();
|
||||
|
||||
//send a SerialPacketBase
|
||||
int SendTo(const char* ip, int port, SerialPacketBase* serialPacket);
|
||||
int SendTo(IPaddress add, SerialPacketBase* serialPacket);
|
||||
int SendTo(int channel, SerialPacketBase* serialPacket);
|
||||
int SendToAllChannels(SerialPacketBase* serialPacket);
|
||||
int Receive(SerialPacketBase* serialPacket);
|
||||
|
||||
//accessors
|
||||
UDPpacket* GetPacket() const {
|
||||
return packet;
|
||||
}
|
||||
UDPsocket GetSocket() const {
|
||||
return socket;
|
||||
}
|
||||
private:
|
||||
friend Singleton<UDPNetworkUtility>;
|
||||
|
||||
UDPNetworkUtility() = default;
|
||||
~UDPNetworkUtility() = default;
|
||||
|
||||
UDPsocket socket = nullptr;
|
||||
UDPpacket* packet = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,188 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "config_utility.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
void ConfigUtility::Load(std::string fname, bool skipMissingFile, int argc, char* argv[]) {
|
||||
//clear the stored configuration
|
||||
configMap.clear();
|
||||
|
||||
//use the default file
|
||||
if (argc < 2) {
|
||||
configMap = Read(fname, skipMissingFile);
|
||||
return;
|
||||
}
|
||||
|
||||
//some variables to use
|
||||
table_t redirectedFile;
|
||||
table_t cmdLineParams;
|
||||
char key[256], val[256];
|
||||
bool redirectUsed = false;
|
||||
|
||||
//reading from the command line
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
//read from a specified config file
|
||||
if (!strncmp(argv[i], "-config=", 8)) {
|
||||
//older specified files take precedence
|
||||
table_t tmp = Read(argv[i] + 8, skipMissingFile);
|
||||
redirectedFile.insert(tmp.begin(), tmp.end());
|
||||
redirectUsed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
//set some specific values
|
||||
if (!strncmp(argv[i], "-", 1)) {
|
||||
//wipe the variables
|
||||
memset(key, 0, 256);
|
||||
memset(key, 0, 256);
|
||||
|
||||
//read the key-value pair
|
||||
if (sscanf(argv[i], "-%[^=]=%[^\0]", key, val) != 2) {
|
||||
std::ostringstream os;
|
||||
os << "Failed to read a command line config argument (expected -%s=%s):" << std::endl;
|
||||
os << "\targv[" << i << "]: " << argv[i] << std::endl;
|
||||
os << "\tkey: " << key << std::endl;
|
||||
os << "\tval: " << val << std::endl;
|
||||
throw(std::runtime_error( os.str() ));
|
||||
}
|
||||
cmdLineParams[key] = val;
|
||||
}
|
||||
}
|
||||
|
||||
//finally, construct the final config table
|
||||
if (!redirectUsed) {
|
||||
redirectedFile = Read(fname, skipMissingFile);
|
||||
}
|
||||
configMap.insert(cmdLineParams.begin(), cmdLineParams.end());
|
||||
configMap.insert(redirectedFile.begin(), redirectedFile.end());
|
||||
}
|
||||
|
||||
ConfigUtility::table_t ConfigUtility::Read(std::string fname, bool skipMissingFile) {
|
||||
//read in and return this file's data
|
||||
table_t retTable;
|
||||
std::ifstream is(fname);
|
||||
|
||||
if (!is.is_open()) {
|
||||
if (skipMissingFile) {
|
||||
return {}; //empty table
|
||||
}
|
||||
std::ostringstream os;
|
||||
os << "Failed to open a config file: " << fname;
|
||||
throw(std::runtime_error( os.str() ));
|
||||
}
|
||||
|
||||
std::string key, val;
|
||||
|
||||
while(true) { //forever
|
||||
//eat whitespace
|
||||
while(isspace(is.peek())) {
|
||||
is.ignore();
|
||||
}
|
||||
|
||||
//end of file
|
||||
if (is.eof()) {
|
||||
break;
|
||||
}
|
||||
|
||||
//skip comment lines
|
||||
if (is.peek() == '#') {
|
||||
while(is.peek() != '\n' && !is.eof()) {
|
||||
is.ignore();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
//read in the pair
|
||||
getline(is, key,'=');
|
||||
getline(is, val);
|
||||
|
||||
//eat the whitespace at the start & end
|
||||
while(key.size() && isspace( *key.begin() )) {
|
||||
key.erase(0, 1);
|
||||
}
|
||||
while(val.size() && isspace( *val.begin() )) {
|
||||
val.erase(0, 1);
|
||||
}
|
||||
|
||||
while(key.size() && isspace( *(key.end()-1) )) {
|
||||
key.erase(key.end() - 1);
|
||||
}
|
||||
while(val.size() && isspace( *(val.end()-1) )) {
|
||||
val.erase(val.end() - 1);
|
||||
}
|
||||
|
||||
//disallow empty/wiped pairs
|
||||
if (key.size() == 0 || val.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//save the pair
|
||||
retTable[key] = val;
|
||||
}
|
||||
|
||||
is.close();
|
||||
|
||||
//load in any subordinate config files
|
||||
if (retTable.find("config.next") != retTable.end()) {
|
||||
table_t subTable = Read(retTable["config.next"], skipMissingFile);
|
||||
retTable.insert(subTable.begin(), subTable.end());
|
||||
}
|
||||
|
||||
return retTable;
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Convert to a type
|
||||
//-------------------------
|
||||
|
||||
std::string& ConfigUtility::String(std::string s) {
|
||||
return configMap[s];
|
||||
}
|
||||
|
||||
int ConfigUtility::Integer(std::string s) {
|
||||
table_t::iterator it = configMap.find(s);
|
||||
if (it == configMap.end()) {
|
||||
return 0;
|
||||
}
|
||||
return atoi(it->second.c_str());
|
||||
}
|
||||
|
||||
double ConfigUtility::Double(std::string s) {
|
||||
table_t::iterator it = configMap.find(s);
|
||||
if (it == configMap.end()) {
|
||||
return 0.0;
|
||||
}
|
||||
return atof(it->second.c_str());
|
||||
}
|
||||
|
||||
bool ConfigUtility::Boolean(std::string s) {
|
||||
table_t::iterator it = configMap.find(s);
|
||||
if (it == configMap.end()) {
|
||||
return false;
|
||||
}
|
||||
return it->second == "true";
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 CONFIGUTILITY_HPP_
|
||||
#define CONFIGUTILITY_HPP_
|
||||
|
||||
#include "singleton.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class ConfigUtility: public Singleton<ConfigUtility> {
|
||||
public:
|
||||
void Load(std::string fname, bool skipMissingFile = false, int argc = 0, char* argv[] = nullptr);
|
||||
|
||||
//convert to a type
|
||||
std::string& String(std::string);
|
||||
int Integer(std::string);
|
||||
double Double(std::string);
|
||||
bool Boolean(std::string);
|
||||
|
||||
//shorthand
|
||||
inline std::string& operator[](std::string s) { return configMap[s]; }
|
||||
inline int Int(std::string s) { return Integer(s); }
|
||||
inline bool Bool(std::string s) { return Boolean(s); }
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, std::string> table_t;
|
||||
|
||||
friend Singleton<ConfigUtility>;
|
||||
|
||||
table_t Read(std::string fname, bool skipMissingFile);
|
||||
|
||||
table_t configMap;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,31 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 IPOPERATORS_HPP_
|
||||
#define IPOPERATORS_HPP_
|
||||
|
||||
#include "SDL/SDL_net.h"
|
||||
|
||||
//these should've come standard
|
||||
bool operator==(IPaddress lhs, IPaddress rhs);
|
||||
bool operator!=(IPaddress lhs, IPaddress rhs);
|
||||
|
||||
#endif
|
||||
@@ -1,63 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 SINGLETON_HPP_
|
||||
#define SINGLETON_HPP_
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
template<typename T>
|
||||
class Singleton {
|
||||
public:
|
||||
static T& GetSingleton() {
|
||||
if (!ptr) {
|
||||
throw(std::logic_error("This singleton has not been created"));
|
||||
}
|
||||
return *ptr;
|
||||
}
|
||||
static void CreateSingleton() {
|
||||
if (ptr) {
|
||||
throw(std::logic_error("This singleton has already been created"));
|
||||
}
|
||||
ptr = new T();
|
||||
}
|
||||
static void DeleteSingleton() {
|
||||
if (!ptr) {
|
||||
throw(std::logic_error("A non-existant singleton cannot be deleted"));
|
||||
}
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
Singleton() = default;
|
||||
Singleton(Singleton const&) = default;
|
||||
Singleton(Singleton&&) = default;
|
||||
~Singleton() = default;
|
||||
|
||||
private:
|
||||
static T* ptr;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T* Singleton<T>::ptr = nullptr;
|
||||
|
||||
#endif
|
||||
@@ -1,15 +0,0 @@
|
||||
Future versions (to be determined) may be released under a modified version of the Uplink Developer's License.
|
||||
|
||||
The current version of Tortuga is released under the zlib license.
|
||||
|
||||
Copyright (c) 2013-2015 Kayne Ruse
|
||||
|
||||
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.
|
||||
@@ -1,35 +0,0 @@
|
||||
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
|
||||
(a public server is provided by default)
|
||||
2. To join a server, your player information must be input into rsc/config.cfg
|
||||
(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, run client.exe, and select 'Start'
|
||||
from the main menu; this displays the list of available servers.
|
||||
7. Select the name of a server (default is 'Public') and select 'Join'.
|
||||
8. Welcome to Tortuga, enjoy your stay.
|
||||
@@ -1,26 +1,17 @@
|
||||
#Windows 7:
|
||||
#for use on Windows:
|
||||
|
||||
#MKDIR=mkdir
|
||||
#RM=del /y
|
||||
|
||||
#Windows 8.1:
|
||||
#RM=del /S
|
||||
#CXXFLAGS+=-static-libgcc -static-libstdc++ -g -fno-inline-functions -Wall
|
||||
#CXXFLAGS+=-static-libgcc -static-libstdc++
|
||||
|
||||
#export
|
||||
|
||||
OUTDIR=out
|
||||
|
||||
all: $(OUTDIR)
|
||||
$(MAKE) -C common
|
||||
$(MAKE) -C server
|
||||
$(MAKE) -C client
|
||||
|
||||
debug: export CXXFLAGS+=-g
|
||||
debug: clean all
|
||||
|
||||
release: export CXXFLAGS+=-static-libgcc -static-libstdc++
|
||||
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 instructions.txt
|
||||
$(MAKE) -C src
|
||||
|
||||
$(OUTDIR):
|
||||
mkdir $(OUTDIR)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
--reroute the program while in development
|
||||
config = {debug = true}
|
||||
dofile("../rsc/setup.lua")
|
||||
@@ -1,31 +0,0 @@
|
||||
#configuration of the programs
|
||||
|
||||
#server specific settings
|
||||
server.host = 255.255.255.255
|
||||
server.port = 21795
|
||||
server.name = local
|
||||
|
||||
server.dbname = database.db
|
||||
|
||||
#client specific settings
|
||||
#client.screen.w = 800
|
||||
#client.screen.h = 600
|
||||
client.screen.f = false
|
||||
|
||||
client.username = username
|
||||
client.handle = handle
|
||||
client.avatar = elliot2.bmp
|
||||
|
||||
#directories
|
||||
dir.fonts = rsc/graphics/fonts/
|
||||
dir.logos = rsc/graphics/logos/
|
||||
dir.sprites = rsc/graphics/sprites/
|
||||
dir.tilesets = rsc/graphics/tilesets/
|
||||
dir.interface = rsc/graphics/interface/
|
||||
dir.scripts = rsc/scripts/
|
||||
dir.maps = rsc/maps/
|
||||
|
||||
#map system
|
||||
map.savename = servermap
|
||||
|
||||
#debugging
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 784 B |
Binary file not shown.
|
Before Width: | Height: | Size: 768 KiB |
@@ -1,63 +0,0 @@
|
||||
local doorUtility = {}
|
||||
|
||||
roomAPI = require("room")
|
||||
regionPagerAPI = require("region_pager")
|
||||
|
||||
triggerAPI = require("trigger")
|
||||
triggerManagerAPI = require("trigger_manager")
|
||||
|
||||
entityAPI = require("entity")
|
||||
characterAPI = require("character")
|
||||
|
||||
networkAPI = require("network")
|
||||
|
||||
function doorUtility.createTrigger(handle, room, x, y, script)
|
||||
local pager = roomAPI.GetPager(room)
|
||||
|
||||
--place the indicator tile
|
||||
regionPagerAPI.SetTile(pager, x / 32, y / 32, 0, mapMaker.dirt)
|
||||
regionPagerAPI.SetTile(pager, x / 32, y / 32, 1, mapMaker.blank)
|
||||
regionPagerAPI.SetTile(pager, x / 32, y / 32, 2, mapMaker.blank)
|
||||
|
||||
--create the trigger object
|
||||
triggerManagerAPI.Create(
|
||||
roomAPI.GetTriggerMgr(room), handle, x, y,
|
||||
0, 0, 32, 32, --size of the tiles
|
||||
script
|
||||
)
|
||||
end
|
||||
|
||||
function doorUtility.createDoorPair(handle, roomOne, Xone, Yone, roomTwo, Xtwo, Ytwo)
|
||||
--create the scripts
|
||||
local function scriptOne(entity)
|
||||
if entityAPI.GetType(entity) ~= "character" then return end
|
||||
|
||||
--move the character
|
||||
characterAPI.SetRoom(entity, roomTwo)
|
||||
characterAPI.SetOrigin(entity, Xtwo, Ytwo-16)
|
||||
networkAPI.PumpCharacterUpdate(entity)
|
||||
|
||||
--disable the other trigger
|
||||
local triggerTwo = triggerManagerAPI.GetTrigger(roomAPI.GetTriggerMgr(roomTwo), handle)
|
||||
triggerAPI.PushExclusionEntity(triggerTwo, entity)
|
||||
end
|
||||
|
||||
local function scriptTwo(entity)
|
||||
if entityAPI.GetType(entity) ~= "character" then return end
|
||||
|
||||
--move the character
|
||||
characterAPI.SetRoom(entity, roomOne)
|
||||
characterAPI.SetOrigin(entity, Xone, Yone-16) --NOTE: the 16 pixel margin for presentation
|
||||
networkAPI.PumpCharacterUpdate(entity)
|
||||
|
||||
--disable the other trigger
|
||||
local triggerOne = triggerManagerAPI.GetTrigger(roomAPI.GetTriggerMgr(roomOne), handle)
|
||||
triggerAPI.PushExclusionEntity(triggerOne, entity)
|
||||
end
|
||||
|
||||
--create the triggers proper
|
||||
doorUtility.createTrigger(handle, roomOne, Xone, Yone, scriptOne)
|
||||
doorUtility.createTrigger(handle, roomTwo, Xtwo, Ytwo, scriptTwo)
|
||||
end
|
||||
|
||||
return doorUtility
|
||||
@@ -0,0 +1,9 @@
|
||||
--overwriting the existing hard coded methods
|
||||
function Region.Load(region)
|
||||
--the return value signals if this succeeded or failed
|
||||
return false
|
||||
end
|
||||
|
||||
function Region.Save(region)
|
||||
--
|
||||
end
|
||||
@@ -0,0 +1,16 @@
|
||||
--uber lazy declarations
|
||||
function math.sqr(x) return x*x end
|
||||
function math.dist(x, y, i, j) return math.sqrt(math.sqr(x-i) + math.sqr(y-j)) end
|
||||
|
||||
--define these
|
||||
function Region.Create(region)
|
||||
for i = 1, Region.GetWidth() do
|
||||
for j = 1, Region.GetHeight() do
|
||||
Region.SetTile(region, i, j, 1, 1) --to show the basics are working
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Region.Unload(region)
|
||||
--
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
local sheet = TileSheet.GetTileSheet()
|
||||
local pager = RegionPager.GetRegionPager()
|
||||
|
||||
--the selected tilesheet
|
||||
TileSheet.Load(sheet, config.dir.tilesets .. "terrain.bmp", 32, 32)
|
||||
|
||||
--tile macros, mapped to this tilesheet
|
||||
local base = 14
|
||||
local shift = 36
|
||||
tiles = {
|
||||
plains = base + shift * 0,
|
||||
grass = base + shift * 1,
|
||||
dirt = base + shift * 2,
|
||||
sand = base + shift * 3,
|
||||
water = base + shift * 4
|
||||
}
|
||||
|
||||
--could set custom generation systems here, that differ from the global generators, etc.
|
||||
function Region.Create(region)
|
||||
for i = 1, Region.GetWidth() do
|
||||
for j = 1, Region.GetHeight() do
|
||||
local dist = math.dist(0, 0, i + Region.GetX(region) -1, j + Region.GetY(region) -1)
|
||||
if dist < 10 then
|
||||
Region.SetTile(region, i, j, 1, tiles.plains)
|
||||
elseif dist < 12 then
|
||||
Region.SetTile(region, i, j, 1, tiles.sand)
|
||||
else
|
||||
Region.SetTile(region, i, j, 1, tiles.water)
|
||||
Region.SetSolid(region, i, j, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,109 +0,0 @@
|
||||
local regionAPI = require("region")
|
||||
|
||||
local mapMaker = {}
|
||||
|
||||
--utility functions
|
||||
function mapMaker.Sqr(x) return x*x end
|
||||
function mapMaker.Dist(x, y, i, j) return math.sqrt(mapMaker.Sqr(x - i) + mapMaker.Sqr(y - j)) end
|
||||
|
||||
--tile macros, mapped to the tilesheet "overworld.bmp"
|
||||
mapMaker.blank = 0
|
||||
mapMaker.water = 18 + 3 * 0
|
||||
mapMaker.sand = 18 + 3 * 1
|
||||
mapMaker.plains = 18 + 3 * 2
|
||||
mapMaker.grass = 18 + 3 * 3
|
||||
mapMaker.dirt = 18 + 3 * 4
|
||||
|
||||
--"edge" macros
|
||||
mapMaker.edges = {}
|
||||
mapMaker.edges.north = -16
|
||||
mapMaker.edges.south = 16
|
||||
mapMaker.edges.east = 1
|
||||
mapMaker.edges.west = -1
|
||||
|
||||
--TODO: (1) path system
|
||||
--use these macros (mapped to "overworld.bmp" for now) to smooth the region's edges
|
||||
function mapMaker.SmoothEdgesSimple(r)
|
||||
--make and pad an array to use
|
||||
local shiftArray = {}
|
||||
for i = 1, regionAPI.GetWidth(r) do
|
||||
shiftArray[i] = {}
|
||||
for j = 1, regionAPI.GetHeight(r) do
|
||||
shiftArray[i][j] = 0
|
||||
end
|
||||
end
|
||||
|
||||
--build the array
|
||||
for i = 1, regionAPI.GetWidth(r) do
|
||||
for j = 1, regionAPI.GetHeight(r) do
|
||||
--if (not regionAPI edge) and (west tile < this tile), etc.
|
||||
if i > 1 and regionAPI.GetTile(r, i - 1, j, 1) < regionAPI.GetTile(r, i, j, 1) then
|
||||
shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.west
|
||||
end
|
||||
if j > 1 and regionAPI.GetTile(r, i, j - 1, 1) < regionAPI.GetTile(r, i, j, 1) then
|
||||
shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.north
|
||||
end
|
||||
if i < regionAPI.GetWidth(r) and regionAPI.GetTile(r, i + 1, j, 1) < regionAPI.GetTile(r, i, j, 1) then
|
||||
shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.east
|
||||
end
|
||||
if j < regionAPI.GetHeight(r) and regionAPI.GetTile(r, i, j + 1, 1) < regionAPI.GetTile(r, i, j, 1) then
|
||||
shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.south
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--finally apply this
|
||||
for i = 1, regionAPI.GetWidth(r) do
|
||||
for j = 1, regionAPI.GetHeight(r) do
|
||||
if shiftArray[i][j] ~= 0 then
|
||||
regionAPI.SetTile(r, i, j, 2, regionAPI.GetTile(r, i, j, 1) + shiftArray[i][j])
|
||||
regionAPI.SetTile(r, i, j, 1, regionAPI.GetTile(r, i, j, 1) - 3)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--custom generation systems here
|
||||
function mapMaker.DebugIsland(r)
|
||||
--basic distance check for each tile, placing an island around the world origin
|
||||
for i = 1, regionAPI.GetWidth(r) do
|
||||
for j = 1, regionAPI.GetHeight(r) do
|
||||
local dist = mapMaker.Dist(0, 0, i + regionAPI.GetX(r) -1, j + regionAPI.GetY(r) -1)
|
||||
if dist < 10 then
|
||||
regionAPI.SetTile(r, i, j, 1, mapMaker.plains)
|
||||
elseif dist < 12 then
|
||||
regionAPI.SetTile(r, i, j, 1, mapMaker.sand)
|
||||
else
|
||||
regionAPI.SetTile(r, i, j, 1, mapMaker.water)
|
||||
regionAPI.SetSolid(r, i, j, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--examples of the smoothing function NOT working correctly
|
||||
--[[
|
||||
for j = 1, regionAPI.GetHeight(r) do
|
||||
regionAPI.SetTile(r, 3, j, 1, mapMaker.dirt)
|
||||
regionAPI.SetTile(r, 4, j, 1, mapMaker.dirt)
|
||||
|
||||
regionAPI.SetTile(r, 10, j, 1, mapMaker.dirt)
|
||||
end
|
||||
--]]
|
||||
|
||||
--A generic edge system
|
||||
mapMaker.SmoothEdgesSimple(r)
|
||||
end
|
||||
|
||||
function mapMaker.DebugGrassland(r)
|
||||
--all dirt
|
||||
for i = 1, regionAPI.GetWidth(r) do
|
||||
for j = 1, regionAPI.GetHeight(r) do
|
||||
regionAPI.SetTile(r, i, j, 1, mapMaker.grass)
|
||||
end
|
||||
end
|
||||
|
||||
--A generic edge system
|
||||
-- mapMaker.SmoothEdgesSimple(r)
|
||||
end
|
||||
|
||||
return mapMaker
|
||||
@@ -1,15 +0,0 @@
|
||||
local region = require("region")
|
||||
|
||||
local mapSaver = {}
|
||||
|
||||
function mapSaver.Load(r)
|
||||
--empty
|
||||
io.write("map_saver:Load(", region.GetX(r), ", ", region.GetY(r), ")\n")
|
||||
end
|
||||
function mapSaver.Save(r)
|
||||
--empty
|
||||
io.write("map_saver:Save(", region.GetX(r), ", ", region.GetY(r), ")\n")
|
||||
end
|
||||
|
||||
--TODO: (3) create a flexible saving & loading system
|
||||
return mapSaver
|
||||
@@ -1,36 +0,0 @@
|
||||
print("Lua script check")
|
||||
|
||||
--requirements
|
||||
roomManagerAPI = require("room_manager")
|
||||
roomAPI = require("room")
|
||||
|
||||
mapMaker = require("map_maker")
|
||||
mapSaver = require("map_saver")
|
||||
|
||||
doorUtility = require("door_utility")
|
||||
|
||||
--test the room hooks
|
||||
roomManagerAPI.SetOnCreate(function(room, index)
|
||||
print("", "Creating room: ", roomAPI.GetName(room), index)
|
||||
|
||||
roomAPI.SetOnTick(room, function(room)
|
||||
roomAPI.ForEachCharacter(room, function(character)
|
||||
--
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
roomManagerAPI.SetOnUnload(function(room, index)
|
||||
print("", "Unloading room: ", roomAPI.GetName(room), index)
|
||||
end)
|
||||
|
||||
--NOTE: room 0 is the first that the client asks for, therefore it must exist
|
||||
local overworld, uidOne = roomManagerAPI.CreateRoom("overworld", "overworld.bmp")
|
||||
roomAPI.Initialize(overworld, mapSaver.Load, mapSaver.Save, mapMaker.DebugIsland, mapSaver.Save)
|
||||
local underworld, uidTwo = roomManagerAPI.CreateRoom("underworld", "overworld.bmp")
|
||||
roomAPI.Initialize(underworld, mapSaver.Load, mapSaver.Save, mapMaker.DebugGrassland, mapSaver.Save)
|
||||
|
||||
--call the monstrosity
|
||||
doorUtility.createDoorPair("pair 1", overworld, 0, -64, underworld, 0, 0)
|
||||
|
||||
print("Finished the lua script")
|
||||
@@ -1,109 +0,0 @@
|
||||
--TODO: (3) An archive table of all dead characters
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Accounts (
|
||||
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username varchar(100) UNIQUE, --TODO: (3) Swap username for email address
|
||||
|
||||
--server-client security
|
||||
-- passhash varchar(100),
|
||||
-- passsalt varchar(100),
|
||||
|
||||
--server controls
|
||||
blacklisted BIT DEFAULT 0,
|
||||
whitelisted BIT DEFAULT 1,
|
||||
mod BIT DEFAULT 0,
|
||||
admin BIT DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Characters (
|
||||
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
|
||||
--metadata
|
||||
owner INTEGER REFERENCES Accounts(uid),
|
||||
handle varchar(100) UNIQUE,
|
||||
avatar varchar(100),
|
||||
birth timestamp NOT NULL DEFAULT (datetime()),
|
||||
|
||||
--physically exists in the world
|
||||
roomIndex INTEGER DEFAULT 0,
|
||||
originX INTEGER DEFAULT 0,
|
||||
originY INTEGER DEFAULT 0,
|
||||
boundsX INTEGER DEFAULT 0,
|
||||
boundsY INTEGER DEFAULT 0,
|
||||
boundsW INTEGER DEFAULT 0,
|
||||
boundsH INTEGER DEFAULT 0,
|
||||
|
||||
--statistics
|
||||
baseStats INTEGER REFERENCES StatisticSets(uid),
|
||||
|
||||
--equipment
|
||||
weapon INTEGER REFERENCES WornEquipment(uid),
|
||||
helmet INTEGER REFERENCES WornEquipment(uid),
|
||||
armour INTEGER REFERENCES WornEquipment(uid)
|
||||
--etc.
|
||||
);
|
||||
|
||||
-------------------------
|
||||
--Utility tables
|
||||
-------------------------
|
||||
|
||||
CREATE TABLE IF NOT EXISTS StatisticSets (
|
||||
--metadata
|
||||
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
|
||||
--general use statistics
|
||||
level INTEGER DEFAULT 0,
|
||||
exp INTEGER DEFAULT 0,
|
||||
maxHP INTEGER DEFAULT 0,
|
||||
health INTEGER DEFAULT 0,
|
||||
maxMP INTEGER DEFAULT 0,
|
||||
mana INTEGER DEFAULT 0,
|
||||
attack INTEGER DEFAULT 0,
|
||||
defence INTEGER DEFAULT 0,
|
||||
intelligence INTEGER DEFAULT 0,
|
||||
resistance INTEGER DEFAULT 0,
|
||||
speed INTEGER DEFAULT 0,
|
||||
accuracy REAL DEFAULT 0.0,
|
||||
evasion REAL DEFAULT 0.0,
|
||||
luck REAL DEFAULT 0.0
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS InWorldItems (
|
||||
--metadata
|
||||
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
itemType INTEGER,
|
||||
|
||||
--position in the world
|
||||
roomIndex INTEGER DEFAULT 0,
|
||||
originX INTEGER DEFAULT 0,
|
||||
originY INTEGER DEFAULT 0,
|
||||
|
||||
--unique information
|
||||
stackSize INTEGER DEFAULT 0,
|
||||
durability INTEGER DEFAULT 0,
|
||||
stats INTEGER REFERENCES StatisticSets(uid)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS InventoryItems (
|
||||
--metadata
|
||||
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
owner INTEGER REFERENCES Characters(uid),
|
||||
itemType INTEGER,
|
||||
|
||||
--unique information
|
||||
stackSize INTEGER DEFAULT 0,
|
||||
durability INTEGER DEFAULT 0,
|
||||
stats INTEGER REFERENCES StatisticSets(uid)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS WornEquipment (
|
||||
--metadata
|
||||
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
owner INTEGER REFERENCES Characters(uid),
|
||||
itemType INTEGER,
|
||||
|
||||
--unique information
|
||||
durability INTEGER DEFAULT 0,
|
||||
stats INTEGER REFERENCES StatisticSets(uid)
|
||||
--attached script?
|
||||
);
|
||||
@@ -0,0 +1,42 @@
|
||||
--[[
|
||||
--reroute the program while in development
|
||||
config = {debug = true}
|
||||
dofile("../rsc/setup.lua")
|
||||
--]]
|
||||
|
||||
--catch the debug signal if the program was rerouted
|
||||
local debug = false
|
||||
if config ~= nil then
|
||||
debug = config.debug
|
||||
end
|
||||
|
||||
--the program's configuration
|
||||
config = {
|
||||
debug = debug,
|
||||
screen = {
|
||||
width = 800,
|
||||
height = 600,
|
||||
fullscreen = false
|
||||
},
|
||||
dir = {
|
||||
fonts = "rsc/graphics/fonts/",
|
||||
logos = "rsc/graphics/logos/",
|
||||
sprites = "rsc/graphics/sprites/",
|
||||
tilesets = "rsc/graphics/tilesets/",
|
||||
interface = "rsc/graphics/interface/",
|
||||
scripts = "rsc/scripts/",
|
||||
maps = "rsc/maps/"
|
||||
},
|
||||
mapname = "mapname"
|
||||
}
|
||||
|
||||
--development environment
|
||||
if config.debug then
|
||||
for k, v in pairs(config.dir) do
|
||||
config.dir[k] = string.format("../%s", v)
|
||||
end
|
||||
end
|
||||
|
||||
--"load" the scripted systems
|
||||
dofile(config.dir.scripts .. "file_format.lua")
|
||||
dofile(config.dir.scripts .. "generator.lua")
|
||||
@@ -1,54 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 ACCOUNTDATA_HPP_
|
||||
#define ACCOUNTDATA_HPP_
|
||||
|
||||
#include <string>
|
||||
|
||||
class AccountData {
|
||||
public:
|
||||
AccountData() = default;
|
||||
~AccountData() = default;
|
||||
|
||||
//accessors and mutators
|
||||
int SetClientIndex(int i);
|
||||
int GetClientIndex();
|
||||
|
||||
std::string SetUsername(std::string s);
|
||||
std::string GetUsername();
|
||||
|
||||
//database stuff
|
||||
bool GetBlackListed();
|
||||
bool GetWhiteListed();
|
||||
bool GetModerator();
|
||||
bool GetAdministrator();
|
||||
|
||||
private:
|
||||
friend class AccountManager;
|
||||
|
||||
int clientIndex;
|
||||
std::string username;
|
||||
//password/auth token
|
||||
|
||||
//bit fields?
|
||||
bool blackListed = false;
|
||||
bool whiteListed = true;
|
||||
bool mod = false;
|
||||
bool admin = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,279 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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_manager.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
//-------------------------
|
||||
//Define the queries
|
||||
//-------------------------
|
||||
|
||||
static const char* CREATE_USER_ACCOUNT = "INSERT INTO Accounts (username) VALUES (?);";
|
||||
|
||||
static const char* LOAD_USER_ACCOUNT = "SELECT "
|
||||
"uid, "
|
||||
"blacklisted, "
|
||||
"whitelisted, "
|
||||
"mod, "
|
||||
"admin "
|
||||
" FROM Accounts WHERE username = ?;";
|
||||
|
||||
static const char* SAVE_USER_ACCOUNT = "UPDATE OR FAIL Accounts SET "
|
||||
"blacklisted = ?2, "
|
||||
"whitelisted = ?3, "
|
||||
"mod = ?4, "
|
||||
"admin = ?5 "
|
||||
"WHERE uid = ?1;";
|
||||
|
||||
static const char* DELETE_USER_ACCOUNT = "DELETE FROM Accounts WHERE uid = ?;";
|
||||
|
||||
static const char* COUNT_USER_ACCOUNT_RECORDS = "SELECT COUNT(*) FROM Accounts;";
|
||||
|
||||
//-------------------------
|
||||
//Define the public methods
|
||||
//-------------------------
|
||||
|
||||
//TODO: (1) block blacklisted accounts
|
||||
int AccountManager::Create(std::string username, int clientIndex) {
|
||||
//create this user account, failing if it exists, leave this account in memory
|
||||
sqlite3_stmt* statement = nullptr;
|
||||
|
||||
//prep
|
||||
if (sqlite3_prepare_v2(database, CREATE_USER_ACCOUNT, -1, &statement, nullptr) != SQLITE_OK) {
|
||||
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//parameter
|
||||
if (sqlite3_bind_text(statement, 1, username.c_str(), username.size() + 1, SQLITE_STATIC) != SQLITE_OK) {
|
||||
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//execute
|
||||
if (sqlite3_step(statement) != SQLITE_DONE) {
|
||||
//if this fails, than this account exists
|
||||
sqlite3_finalize(statement);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sqlite3_finalize(statement);
|
||||
|
||||
//load this account into memory
|
||||
return Load(username, clientIndex);
|
||||
}
|
||||
|
||||
int AccountManager::Load(std::string username, int clientIndex) {
|
||||
//load this user account, failing if it is in memory, creating it if it doesn't exist
|
||||
sqlite3_stmt* statement = nullptr;
|
||||
|
||||
//prep
|
||||
if (sqlite3_prepare_v2(database, LOAD_USER_ACCOUNT, -1, &statement, nullptr) != SQLITE_OK) {
|
||||
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//parameter
|
||||
if (sqlite3_bind_text(statement, 1, username.c_str(), username.size() + 1, SQLITE_STATIC) != SQLITE_OK) {
|
||||
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//execute
|
||||
int ret = sqlite3_step(statement);
|
||||
|
||||
//process the result
|
||||
if (ret == SQLITE_ROW) {
|
||||
//get the index
|
||||
int uid = sqlite3_column_int(statement, 0);
|
||||
|
||||
//check to see if this account is already loaded
|
||||
if (elementMap.find(uid) != elementMap.end()) {
|
||||
sqlite3_finalize(statement);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//extract the data into memory
|
||||
AccountData& newAccount = elementMap[uid];
|
||||
newAccount.username = username;
|
||||
newAccount.blackListed = sqlite3_column_int(statement, 1);
|
||||
newAccount.whiteListed = sqlite3_column_int(statement, 2);
|
||||
newAccount.mod = sqlite3_column_int(statement, 3);
|
||||
newAccount.admin = sqlite3_column_int(statement, 4);
|
||||
newAccount.clientIndex = clientIndex;
|
||||
|
||||
//finish the routine
|
||||
sqlite3_finalize(statement);
|
||||
return uid;
|
||||
}
|
||||
|
||||
sqlite3_finalize(statement);
|
||||
|
||||
if (ret == SQLITE_DONE) {
|
||||
//create the non-existant account instead
|
||||
return Create(username, clientIndex);
|
||||
}
|
||||
|
||||
throw(std::runtime_error(std::string() + "Unknown SQL error in LoadAccount: " + sqlite3_errmsg(database) ));
|
||||
}
|
||||
|
||||
int AccountManager::Save(int uid) {
|
||||
//save this user account from memory, replacing it if it exists in the database
|
||||
//DOCS: To use this method, change the in-memory copy, and then call this function using that object's UID.
|
||||
|
||||
//this method fails if this account is not loaded
|
||||
if (elementMap.find(uid) == elementMap.end()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
AccountData& account = elementMap[uid];
|
||||
sqlite3_stmt* statement = nullptr;
|
||||
|
||||
//prep
|
||||
if (sqlite3_prepare_v2(database, SAVE_USER_ACCOUNT, -1, &statement, nullptr) != SQLITE_OK) {
|
||||
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//parameters
|
||||
bool ret = false;
|
||||
ret |= sqlite3_bind_int(statement, 1, uid) != SQLITE_OK;
|
||||
ret |= sqlite3_bind_int(statement, 2, account.blackListed) != SQLITE_OK;
|
||||
ret |= sqlite3_bind_int(statement, 3, account.whiteListed) != SQLITE_OK;
|
||||
ret |= sqlite3_bind_int(statement, 4, account.mod) != SQLITE_OK;
|
||||
ret |= sqlite3_bind_int(statement, 5, account.admin) != SQLITE_OK;
|
||||
|
||||
//check for binding errors
|
||||
if (ret) {
|
||||
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//execute
|
||||
if (sqlite3_step(statement) != SQLITE_DONE) {
|
||||
//if this fails, than something went horribly wrong
|
||||
sqlite3_finalize(statement);
|
||||
throw( std::runtime_error(std::string() + "Unknown SQL error when saving an account: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
sqlite3_finalize(statement);
|
||||
|
||||
//successful execution
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AccountManager::Unload(int uid) {
|
||||
//save this user account, and then unload it
|
||||
//NOTE: the associated characters are unloaded externally
|
||||
Save(uid);
|
||||
elementMap.erase(uid);
|
||||
}
|
||||
|
||||
void AccountManager::Delete(int uid) {
|
||||
//delete a user account from the database, and remove it from memory
|
||||
//NOTE: the associated characters should be deleted externally
|
||||
sqlite3_stmt* statement = nullptr;
|
||||
|
||||
//prep
|
||||
if (sqlite3_prepare_v2(database, DELETE_USER_ACCOUNT, -1, &statement, nullptr) != SQLITE_OK) {
|
||||
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//parameter
|
||||
if (sqlite3_bind_int(statement, 1, uid) != SQLITE_OK) {
|
||||
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//execute
|
||||
if (sqlite3_step(statement) != SQLITE_DONE) {
|
||||
//if this fails, than something went horribly wrong
|
||||
sqlite3_finalize(statement);
|
||||
throw( std::runtime_error(std::string() + "Unknown SQL error when deleting an account: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//finish the routine
|
||||
sqlite3_finalize(statement);
|
||||
elementMap.erase(uid);
|
||||
}
|
||||
|
||||
void AccountManager::UnloadAll() {
|
||||
for (auto& it : elementMap) {
|
||||
Save(it.first);
|
||||
}
|
||||
elementMap.clear();
|
||||
}
|
||||
|
||||
void AccountManager::UnloadIf(std::function<bool(std::pair<const int, AccountData const&>)> fn) {
|
||||
//replicate std::remove_if, using custom code
|
||||
std::map<int, AccountData>::iterator it = elementMap.begin();
|
||||
while (it != elementMap.end()) {
|
||||
if (fn(*it)) {
|
||||
Save(it->first);
|
||||
it = elementMap.erase(it);
|
||||
}
|
||||
else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Define the accessors and mutators
|
||||
//-------------------------
|
||||
|
||||
AccountData* AccountManager::Get(int uid) {
|
||||
std::map<int, AccountData>::iterator it = elementMap.find(uid);
|
||||
|
||||
if (it == elementMap.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
int AccountManager::GetLoadedCount() {
|
||||
return elementMap.size();
|
||||
}
|
||||
|
||||
int AccountManager::GetTotalCount() {
|
||||
//a lot just to count something.
|
||||
sqlite3_stmt* statement = nullptr;
|
||||
|
||||
//prep
|
||||
if (sqlite3_prepare_v2(database, COUNT_USER_ACCOUNT_RECORDS, -1, &statement, nullptr) != SQLITE_OK) {
|
||||
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//execute & retrieve the result
|
||||
sqlite3_step(statement);
|
||||
int ret = sqlite3_column_int(statement, 0);
|
||||
|
||||
//finish the routine
|
||||
sqlite3_finalize(statement);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::map<int, AccountData>* AccountManager::GetContainer() {
|
||||
return &elementMap;
|
||||
}
|
||||
|
||||
sqlite3* AccountManager::SetDatabase(sqlite3* db) {
|
||||
return database = db;
|
||||
}
|
||||
|
||||
sqlite3* AccountManager::GetDatabase() {
|
||||
return database;
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 ACCOUNTMANAGER_HPP_
|
||||
#define ACCOUNTMANAGER_HPP_
|
||||
|
||||
#include "account_data.hpp"
|
||||
#include "singleton.hpp"
|
||||
|
||||
#include "sqlite3.h"
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
||||
class AccountManager: public Singleton<AccountManager> {
|
||||
public:
|
||||
//common public methods
|
||||
int Create(std::string username, int clientIndex);
|
||||
int Load(std::string username, int clientIndex);
|
||||
int Save(int uid);
|
||||
void Unload(int uid);
|
||||
void Delete(int uid);
|
||||
|
||||
void UnloadAll();
|
||||
void UnloadIf(std::function<bool(std::pair<const int, AccountData const&>)> fn);
|
||||
|
||||
//accessors and mutators
|
||||
AccountData* Get(int uid);
|
||||
int GetLoadedCount();
|
||||
int GetTotalCount();
|
||||
std::map<int, AccountData>* GetContainer();
|
||||
|
||||
sqlite3* SetDatabase(sqlite3* db);
|
||||
sqlite3* GetDatabase();
|
||||
|
||||
private:
|
||||
friend Singleton<AccountManager>;
|
||||
|
||||
AccountManager() = default;
|
||||
~AccountManager() = default;
|
||||
|
||||
//members
|
||||
std::map<int, AccountData> elementMap;
|
||||
sqlite3* database = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,37 +0,0 @@
|
||||
#config
|
||||
INCLUDES+=. ../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
|
||||
@@ -1,129 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "character_api.hpp"
|
||||
|
||||
#include "character_data.hpp"
|
||||
#include "character_manager.hpp"
|
||||
#include "entity_api.hpp"
|
||||
#include "room_manager.hpp"
|
||||
#include "server_utilities.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
static int setRoom(lua_State* L) {
|
||||
//reverse engineer the character index
|
||||
int characterIndex = -1;
|
||||
CharacterData* character = static_cast<CharacterData*>(lua_touserdata(L, 1));
|
||||
CharacterManager& characterMgr = CharacterManager::GetSingleton();
|
||||
|
||||
for (auto& it : *characterMgr.GetContainer()) {
|
||||
if (character == &it.second) {
|
||||
characterIndex = it.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//error checking
|
||||
if (characterIndex == -1) {
|
||||
throw(std::runtime_error("Lua Error: Failed to find character index by reference"));
|
||||
}
|
||||
|
||||
//get the room index, depending on the parameter type
|
||||
int roomIndex = -1;
|
||||
RoomManager& roomMgr = RoomManager::GetSingleton();
|
||||
switch(lua_type(L, 2)) {
|
||||
case LUA_TNUMBER:
|
||||
roomIndex = lua_tointeger(L, 2);
|
||||
break;
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
//reverse engineer the room index
|
||||
for (auto& it : *roomMgr.GetContainer()) {
|
||||
if (lua_touserdata(L, 2) == &it.second) {
|
||||
roomIndex = it.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//error checking
|
||||
if (roomIndex == -1) {
|
||||
throw(std::runtime_error("Lua Error: Failed to find room index by reference"));
|
||||
}
|
||||
|
||||
//send the delete & create messages
|
||||
pumpAndChangeRooms(character, roomIndex, characterIndex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getOwner(lua_State* L) {
|
||||
CharacterData* character = static_cast<CharacterData*>(lua_touserdata(L, 1));
|
||||
lua_pushinteger(L, character->GetOwner());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int getHandle(lua_State* L) {
|
||||
CharacterData* character = static_cast<CharacterData*>(lua_touserdata(L, 1));
|
||||
lua_pushstring(L, character->GetHandle().c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int getAvatar(lua_State* L) {
|
||||
CharacterData* character = static_cast<CharacterData*>(lua_touserdata(L, 1));
|
||||
lua_pushstring(L, character->GetAvatar().c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_Reg characterLib[] = {
|
||||
{"SetRoom", setRoom},
|
||||
// {"GetOwner", getOwner}, //unusable without account API
|
||||
{"GetHandle", getHandle},
|
||||
{"GetAvatar", getAvatar},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
||||
LUAMOD_API int openCharacterAPI(lua_State* L) {
|
||||
//get the parent table
|
||||
luaL_requiref(L, TORTUGA_ENTITY_API, openEntityAPI, false);
|
||||
|
||||
//the local table
|
||||
luaL_newlib(L, characterLib);
|
||||
|
||||
//merge the local table into the parent table
|
||||
lua_pushnil(L); //first key
|
||||
while(lua_next(L, -2)) {
|
||||
//copy the key-value pair
|
||||
lua_pushvalue(L, -2);
|
||||
lua_pushvalue(L, -2);
|
||||
|
||||
//push the copy to the parent table
|
||||
lua_settable(L, -6);
|
||||
|
||||
//pop the original value before continuing
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
//remove the local table, leaving the expanded parent table
|
||||
lua_pop(L, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 CHARACTERAPI_HPP_
|
||||
#define CHARACTERAPI_HPP_
|
||||
|
||||
#include "lua.hpp"
|
||||
|
||||
#define TORTUGA_CHARACTER_API "character"
|
||||
LUAMOD_API int openCharacterAPI(lua_State* L);
|
||||
|
||||
#endif
|
||||
@@ -1,38 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "character_data.hpp"
|
||||
|
||||
CharacterData::CharacterData(): Entity("character") {
|
||||
//EMPTY
|
||||
}
|
||||
|
||||
int CharacterData::GetOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
std::string CharacterData::GetHandle() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
std::string CharacterData::GetAvatar() {
|
||||
return avatar;
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 CHARACTERDATA_HPP_
|
||||
#define CHARACTERDATA_HPP_
|
||||
|
||||
//components
|
||||
#include "character_defines.hpp"
|
||||
#include "entity.hpp"
|
||||
|
||||
//std namespace
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
|
||||
class CharacterData: public Entity {
|
||||
public:
|
||||
CharacterData();
|
||||
~CharacterData() = default;
|
||||
|
||||
//database stuff
|
||||
int GetOwner();
|
||||
std::string GetHandle();
|
||||
std::string GetAvatar();
|
||||
|
||||
private:
|
||||
friend class CharacterManager;
|
||||
|
||||
int owner = -1;
|
||||
std::string handle;
|
||||
std::string avatar;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,347 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "character_manager.hpp"
|
||||
|
||||
#include "sqlite3.h"
|
||||
|
||||
#include "character_defines.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
//-------------------------
|
||||
//Define the queries
|
||||
//-------------------------
|
||||
|
||||
//NOTE: Programmer set variables are NOT zero-indexed
|
||||
//NOTE: SQLite3 returned variables (i.e. loading) ARE zero-indexed
|
||||
|
||||
static const char* CREATE_CHARACTER = "INSERT INTO Characters ("
|
||||
"owner, "
|
||||
"handle, "
|
||||
"avatar, "
|
||||
"boundsX, "
|
||||
"boundsY, "
|
||||
"boundsW, "
|
||||
"boundsH"
|
||||
") VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7);";
|
||||
|
||||
static const char* LOAD_CHARACTER = "SELECT "
|
||||
"uid, "
|
||||
"owner, "
|
||||
"handle, "
|
||||
"avatar, "
|
||||
"roomIndex, "
|
||||
"originX, "
|
||||
"originY, "
|
||||
"boundsX, "
|
||||
"boundsY, "
|
||||
"boundsW, "
|
||||
"boundsH "
|
||||
"FROM Characters WHERE handle = ?;";
|
||||
|
||||
static const char* SAVE_CHARACTER = "UPDATE OR FAIL Characters SET "
|
||||
"roomIndex = ?2, "
|
||||
"originX = ?3, "
|
||||
"originY = ?4, "
|
||||
"boundsX = ?5, "
|
||||
"boundsY = ?6, "
|
||||
"boundsW = ?7, "
|
||||
"boundsH = ?8 "
|
||||
"WHERE uid = ?1;";
|
||||
|
||||
static const char* DELETE_CHARACTER = "DELETE FROM Characters WHERE uid = ?;";
|
||||
|
||||
static const char* COUNT_CHARACTER_RECORDS = "SELECT COUNT(*) FROM Characters;";
|
||||
|
||||
//-------------------------
|
||||
//Define the methods
|
||||
//-------------------------
|
||||
|
||||
//NOTE: default baseStats as a parameter would be good for different beggining states or multiple classes
|
||||
int CharacterManager::Create(int owner, std::string handle, std::string avatar) {
|
||||
//Create the character, failing if it exists
|
||||
sqlite3_stmt* statement = nullptr;
|
||||
|
||||
//prep
|
||||
if (sqlite3_prepare_v2(database, CREATE_CHARACTER, -1, &statement, nullptr) != SQLITE_OK) {
|
||||
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//parameters
|
||||
bool ret = false;
|
||||
ret |= sqlite3_bind_int(statement, 1, owner);
|
||||
ret |= sqlite3_bind_text(statement, 2, handle.c_str(), handle.size() + 1, SQLITE_STATIC);
|
||||
ret |= sqlite3_bind_text(statement, 3, avatar.c_str(), avatar.size() + 1, SQLITE_STATIC);
|
||||
ret |= sqlite3_bind_int(statement, 4, CHARACTER_BOUNDS_X);
|
||||
ret |= sqlite3_bind_int(statement, 5, CHARACTER_BOUNDS_Y);
|
||||
ret |= sqlite3_bind_int(statement, 6, CHARACTER_BOUNDS_WIDTH);
|
||||
ret |= sqlite3_bind_int(statement, 7, CHARACTER_BOUNDS_HEIGHT);
|
||||
|
||||
//check for binding errors
|
||||
if (ret) {
|
||||
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//execute
|
||||
if (sqlite3_step(statement) != SQLITE_DONE) {
|
||||
//if this fails, than this character exists
|
||||
sqlite3_finalize(statement);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sqlite3_finalize(statement);
|
||||
|
||||
//load this character into memory
|
||||
return Load(owner, handle, avatar);
|
||||
}
|
||||
|
||||
int CharacterManager::Load(int owner, std::string handle, std::string avatar) {
|
||||
//load the specified character, creating it if it doesn't exist
|
||||
//fail if it is already loaded, or does not belong to this account
|
||||
sqlite3_stmt* statement = nullptr;
|
||||
|
||||
//prep
|
||||
if (sqlite3_prepare_v2(database, LOAD_CHARACTER, -1, &statement, nullptr) != SQLITE_OK) {
|
||||
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//parameter
|
||||
if (sqlite3_bind_text(statement, 1, handle.c_str(), handle.size() + 1, SQLITE_STATIC) != SQLITE_OK) {
|
||||
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//execute
|
||||
int ret = sqlite3_step(statement);
|
||||
|
||||
//process the result
|
||||
if (ret == SQLITE_ROW) {
|
||||
//get the index
|
||||
int uid = sqlite3_column_int(statement, 0);
|
||||
|
||||
//check to see if this character is already loaded
|
||||
if (elementMap.find(uid) != elementMap.end()) {
|
||||
sqlite3_finalize(statement);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//check the owner
|
||||
if (owner != sqlite3_column_int(statement, 1)) {
|
||||
sqlite3_finalize(statement);
|
||||
//unload the already loaded character
|
||||
Unload(uid);
|
||||
return -2;
|
||||
}
|
||||
|
||||
//extract the data into memory
|
||||
CharacterData& newChar = elementMap[uid];
|
||||
|
||||
//metadata
|
||||
newChar.owner = owner;
|
||||
newChar.handle = reinterpret_cast<const char*>(sqlite3_column_text(statement, 2));
|
||||
newChar.avatar = reinterpret_cast<const char*>(sqlite3_column_text(statement, 3));
|
||||
//Don't cache the birth
|
||||
|
||||
//world origin
|
||||
newChar.roomIndex = sqlite3_column_int(statement, 4);
|
||||
newChar.origin.x = (double)sqlite3_column_int(statement, 5);
|
||||
newChar.origin.y = (double)sqlite3_column_int(statement, 6);
|
||||
//bounds
|
||||
newChar.bounds.x = (int)sqlite3_column_int(statement, 7);
|
||||
newChar.bounds.y = (int)sqlite3_column_int(statement, 8);
|
||||
newChar.bounds.w = (int)sqlite3_column_int(statement, 9);
|
||||
newChar.bounds.h = (int)sqlite3_column_int(statement, 10);
|
||||
|
||||
//gameplay components: equipment, items, buffs, debuffs...
|
||||
|
||||
//finish the routine
|
||||
sqlite3_finalize(statement);
|
||||
return uid;
|
||||
}
|
||||
|
||||
sqlite3_finalize(statement);
|
||||
|
||||
if (ret == SQLITE_DONE) {
|
||||
//create the non-existant character instead
|
||||
return Create(owner, handle, avatar);
|
||||
}
|
||||
|
||||
throw(std::runtime_error(std::string() + "Unknown SQL error in LoadCharacter: " + sqlite3_errmsg(database) ));
|
||||
}
|
||||
|
||||
int CharacterManager::Save(int uid) {
|
||||
//save this character from memory, replacing it if it exists in the database
|
||||
//DOCS: To use this method, change the in-memory copy, and then call this function using that object's UID.
|
||||
|
||||
//this method fails if this character is not loaded
|
||||
if (elementMap.find(uid) == elementMap.end()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
CharacterData& character = elementMap[uid];
|
||||
sqlite3_stmt* statement = nullptr;
|
||||
|
||||
//prep
|
||||
if (sqlite3_prepare_v2(database, SAVE_CHARACTER, -1, &statement, nullptr) != SQLITE_OK) {
|
||||
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//parameters
|
||||
bool ret = false;
|
||||
ret |= sqlite3_bind_int(statement, 1, uid) != SQLITE_OK;
|
||||
ret |= sqlite3_bind_int(statement, 2, character.roomIndex) != SQLITE_OK;
|
||||
ret |= sqlite3_bind_int(statement, 3, (int)character.origin.x) != SQLITE_OK;
|
||||
ret |= sqlite3_bind_int(statement, 4, (int)character.origin.y) != SQLITE_OK;
|
||||
ret |= sqlite3_bind_int(statement, 5, character.bounds.x) != SQLITE_OK;
|
||||
ret |= sqlite3_bind_int(statement, 6, character.bounds.y) != SQLITE_OK;
|
||||
ret |= sqlite3_bind_int(statement, 7, character.bounds.w) != SQLITE_OK;
|
||||
ret |= sqlite3_bind_int(statement, 8, character.bounds.h) != SQLITE_OK;
|
||||
|
||||
//gameplay components: equipment, items, buffs, debuffs...
|
||||
|
||||
//check for binding errors
|
||||
if (ret) {
|
||||
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//execute
|
||||
if (sqlite3_step(statement) != SQLITE_DONE) {
|
||||
//if this fails, than something went horribly wrong
|
||||
sqlite3_finalize(statement);
|
||||
throw( std::runtime_error(std::string() + "Unknown SQL error when saving a character: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
sqlite3_finalize(statement);
|
||||
|
||||
//successful execution
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CharacterManager::Unload(int uid) {
|
||||
//save this character, then unload it
|
||||
Save(uid);
|
||||
elementMap.erase(uid);
|
||||
}
|
||||
|
||||
void CharacterManager::Delete(int uid) {
|
||||
//TODO: when deleting a character, move it to an archive table
|
||||
//delete this character from the database, then remove it from memory
|
||||
sqlite3_stmt* statement = nullptr;
|
||||
|
||||
//prep
|
||||
if (sqlite3_prepare_v2(database, DELETE_CHARACTER, -1, &statement, nullptr) != SQLITE_OK) {
|
||||
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//parameter
|
||||
if (sqlite3_bind_int(statement, 1, uid) != SQLITE_OK) {
|
||||
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//execute
|
||||
if (sqlite3_step(statement) != SQLITE_DONE) {
|
||||
//if this fails, than something went horribly wrong
|
||||
sqlite3_finalize(statement);
|
||||
throw( std::runtime_error(std::string() + "Unknown SQL error when deleting a character: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//finish the routine
|
||||
sqlite3_finalize(statement);
|
||||
elementMap.erase(uid);
|
||||
}
|
||||
|
||||
void CharacterManager::UnloadAll() {
|
||||
for (auto& it : elementMap) {
|
||||
Save(it.first);
|
||||
}
|
||||
elementMap.clear();
|
||||
}
|
||||
|
||||
void CharacterManager::UnloadIf(std::function<bool(std::pair<const int, CharacterData const&>)> fn) {
|
||||
std::map<int, CharacterData>::iterator it = elementMap.begin();
|
||||
while (it != elementMap.end()) {
|
||||
if (fn(*it)) {
|
||||
Save(it->first);
|
||||
it = elementMap.erase(it);
|
||||
}
|
||||
else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
//Define the accessors and mutators
|
||||
//-------------------------
|
||||
|
||||
CharacterData* CharacterManager::Get(int uid) {
|
||||
std::map<int, CharacterData>::iterator it = elementMap.find(uid);
|
||||
|
||||
if (it == elementMap.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
CharacterData* CharacterManager::Get(std::string handle) {
|
||||
for (std::map<int, CharacterData>::iterator it = elementMap.begin(); it != elementMap.end(); ++it) {
|
||||
if (it->second.GetHandle() == handle) {
|
||||
return &it->second;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int CharacterManager::GetLoadedCount() {
|
||||
return elementMap.size();
|
||||
}
|
||||
|
||||
int CharacterManager::GetTotalCount() {
|
||||
//a lot just to count something.
|
||||
sqlite3_stmt* statement = nullptr;
|
||||
|
||||
//prep
|
||||
if (sqlite3_prepare_v2(database, COUNT_CHARACTER_RECORDS, -1, &statement, nullptr) != SQLITE_OK) {
|
||||
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
|
||||
}
|
||||
|
||||
//execute & retrieve the result
|
||||
sqlite3_step(statement);
|
||||
int ret = sqlite3_column_int(statement, 0);
|
||||
|
||||
//finish the routine
|
||||
sqlite3_finalize(statement);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::map<int, CharacterData>* CharacterManager::GetContainer() {
|
||||
return &elementMap;
|
||||
}
|
||||
|
||||
sqlite3* CharacterManager::SetDatabase(sqlite3* db) {
|
||||
return database = db;
|
||||
}
|
||||
|
||||
sqlite3* CharacterManager::GetDatabase() {
|
||||
return database;
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 CHARACTERMANAGER_HPP_
|
||||
#define CHARACTERMANAGER_HPP_
|
||||
|
||||
#include "character_data.hpp"
|
||||
#include "singleton.hpp"
|
||||
|
||||
#include "sqlite3.h"
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
||||
class CharacterManager: public Singleton<CharacterManager> {
|
||||
public:
|
||||
//common public methods
|
||||
int Create(int owner, std::string handle, std::string avatar);
|
||||
int Load(int owner, std::string handle, std::string avatar);
|
||||
int Save(int uid);
|
||||
void Unload(int uid);
|
||||
void Delete(int uid);
|
||||
|
||||
void UnloadAll();
|
||||
void UnloadIf(std::function<bool(std::pair<const int, CharacterData const&>)> fn);
|
||||
|
||||
//accessors and mutators
|
||||
CharacterData* Get(int uid);
|
||||
CharacterData* Get(std::string handle);
|
||||
int GetLoadedCount();
|
||||
int GetTotalCount();
|
||||
std::map<int, CharacterData>* GetContainer();
|
||||
|
||||
//API interface
|
||||
sqlite3* SetDatabase(sqlite3* db);
|
||||
sqlite3* GetDatabase();
|
||||
|
||||
//hooks
|
||||
//TODO: character hooks
|
||||
|
||||
private:
|
||||
friend Singleton<CharacterManager>;
|
||||
|
||||
CharacterManager() = default;
|
||||
~CharacterManager() = default;
|
||||
|
||||
//members
|
||||
std::map<int, CharacterData> elementMap;
|
||||
sqlite3* database = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,114 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "character_manager_api.hpp"
|
||||
|
||||
#include "character_manager.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
//TODO: (1) character hooks?
|
||||
|
||||
static int setOnCreate(lua_State* L) {
|
||||
//TODO: (9) setOnCreate()
|
||||
}
|
||||
|
||||
static int setOnLoad(lua_State* L) {
|
||||
//TODO: (9) setOnLoad()
|
||||
}
|
||||
|
||||
static int setOnSave(lua_State* L) {
|
||||
//TODO: (9) setOnSave()
|
||||
}
|
||||
|
||||
static int setOnUnload(lua_State* L) {
|
||||
//TODO: (9) setOnUnload()
|
||||
}
|
||||
|
||||
static int setOnDelete(lua_State* L) {
|
||||
//TODO: (9) setOnDelete()
|
||||
}
|
||||
|
||||
static int getCharacter(lua_State* L) {
|
||||
//integer vs name
|
||||
CharacterManager& characterMgr = CharacterManager::GetSingleton();
|
||||
CharacterData* characterData = nullptr;
|
||||
|
||||
switch(lua_type(L, 1)) {
|
||||
case LUA_TNUMBER:
|
||||
characterData = characterMgr.Get(lua_tointeger(L, 1));
|
||||
break;
|
||||
case LUA_TSTRING:
|
||||
//access characters via their handles
|
||||
characterData = characterMgr.Get(lua_tostring(L, 1));
|
||||
break;
|
||||
}
|
||||
|
||||
if (characterData) {
|
||||
lua_pushlightuserdata(L, static_cast<void*>(characterData));
|
||||
}
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int getLoadedCount(lua_State* L) {
|
||||
CharacterManager& characterMgr = CharacterManager::GetSingleton();
|
||||
lua_pushinteger(L, characterMgr.GetLoadedCount());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int forEach(lua_State* L) {
|
||||
CharacterManager& characterMgr = CharacterManager::GetSingleton();
|
||||
//pass each character to the given function
|
||||
for (auto& it : *characterMgr.GetContainer()) {
|
||||
lua_pushvalue(L, -1);
|
||||
lua_pushlightuserdata(L, static_cast<void*>(&it.second));
|
||||
//call each iteration, throwing an exception if something happened
|
||||
if (lua_pcall(L, 1, 0, 0) != LUA_OK) {
|
||||
std::ostringstream os;
|
||||
os << "Lua error: ";
|
||||
os << lua_tostring(L, -1);
|
||||
throw(std::runtime_error(os.str()));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const luaL_Reg characterManagerLib[] = {
|
||||
// {"SetOnCreate", setOnCreate},
|
||||
// {"SetOnLoad", setOnLoad},
|
||||
// {"SetOnSave", setOnSave},
|
||||
// {"SetOnUnload", setOnUnload},
|
||||
// {"SetOnDelete", setOnDelete},
|
||||
{"GetCharacter", getCharacter},
|
||||
{"GetLoadedCount", getLoadedCount},
|
||||
{"ForEach", forEach},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
||||
LUAMOD_API int openCharacterManagerAPI(lua_State* L) {
|
||||
luaL_newlib(L, characterManagerLib);
|
||||
return 1;
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 CHARACTERMANAGERAPI_HPP_
|
||||
#define CHARACTERMANAGERAPI_HPP_
|
||||
|
||||
#include "lua.hpp"
|
||||
|
||||
#define TORTUGA_CHARACTER_MANAGER_API "character_manager"
|
||||
LUAMOD_API int openCharacterManagerAPI(lua_State* L);
|
||||
|
||||
#endif
|
||||
@@ -1,37 +0,0 @@
|
||||
#config
|
||||
INCLUDES+=. ../entities ../monsters ../rooms ../server_utilities ../triggers ../../common/gameplay ../../common/map ../../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
|
||||
@@ -1,52 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#include "client_data.hpp"
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
int ClientData::ResetAttempts() {
|
||||
lastBeat = Clock::now();
|
||||
return attemptedBeats = 0;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 CLIENTDATA_HPP_
|
||||
#define CLIENTDATA_HPP_
|
||||
|
||||
#include "SDL/SDL_net.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
class ClientData {
|
||||
public:
|
||||
typedef std::chrono::steady_clock Clock;
|
||||
|
||||
ClientData() = default;
|
||||
ClientData(IPaddress add);
|
||||
~ClientData() = default;
|
||||
|
||||
IPaddress SetAddress(IPaddress add);
|
||||
IPaddress GetAddress();
|
||||
|
||||
Clock::time_point GetLastBeat();
|
||||
|
||||
int GetAttempts();
|
||||
int IncrementAttempts();
|
||||
int ResetAttempts();
|
||||
|
||||
private:
|
||||
IPaddress address = {0,0};
|
||||
|
||||
Clock::time_point lastBeat = Clock::now();
|
||||
int attemptedBeats = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,108 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "ip_operators.hpp"
|
||||
#include "udp_network_utility.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
std::list<int> ClientManager::CheckConnections() {
|
||||
//list of clients to disconnect
|
||||
std::list<int> returnList;
|
||||
|
||||
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) {
|
||||
returnList.push_back(it.first);
|
||||
}
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
void ClientManager::HandlePong(ServerPacket* const argPacket) {
|
||||
//find and update the specified client
|
||||
for (auto& it : elementMap) {
|
||||
if (it.second.GetAddress() == argPacket->srcAddress) {
|
||||
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 const&>)> fn) {
|
||||
std::map<int, ClientData>::iterator it = elementMap.begin();
|
||||
while (it != elementMap.end()) {
|
||||
if (fn(*it)) {
|
||||
it = elementMap.erase(it);
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "server_packet.hpp"
|
||||
#include "singleton.hpp"
|
||||
|
||||
#include "SDL/SDL_net.h"
|
||||
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
class ClientManager: public Singleton<ClientManager> {
|
||||
public:
|
||||
//methods
|
||||
std::list<int> CheckConnections();
|
||||
void HandlePong(ServerPacket* const argPacket);
|
||||
|
||||
//common public methods
|
||||
int Create(IPaddress);
|
||||
void Unload(int uid);
|
||||
|
||||
void UnloadAll();
|
||||
void UnloadIf(std::function<bool(std::pair<const int, ClientData const&>)> fn);
|
||||
|
||||
//accessors & mutators
|
||||
ClientData* Get(int uid);
|
||||
int GetLoadedCount();
|
||||
int GetTotalCount();
|
||||
std::map<int, ClientData>* GetContainer();
|
||||
|
||||
private:
|
||||
friend Singleton<ClientManager>;
|
||||
|
||||
ClientManager() = default;
|
||||
~ClientManager() = default;
|
||||
|
||||
//members
|
||||
std::map<int, ClientData> elementMap;
|
||||
int counter = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,37 +0,0 @@
|
||||
#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
|
||||
@@ -1,66 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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"
|
||||
|
||||
Entity::Entity(const char* _type): type(_type) {
|
||||
//EMPTY
|
||||
}
|
||||
|
||||
void Entity::Update() {
|
||||
origin += motion;
|
||||
}
|
||||
|
||||
int Entity::SetRoomIndex(int i) {
|
||||
return roomIndex = i;
|
||||
}
|
||||
|
||||
Vector2 Entity::SetOrigin(Vector2 v) {
|
||||
return origin = v;
|
||||
}
|
||||
|
||||
Vector2 Entity::SetMotion(Vector2 v) {
|
||||
return motion = v;
|
||||
}
|
||||
|
||||
BoundingBox Entity::SetBounds(BoundingBox b) {
|
||||
return bounds = b;
|
||||
}
|
||||
|
||||
int Entity::GetRoomIndex() const {
|
||||
return roomIndex;
|
||||
}
|
||||
|
||||
Vector2 Entity::GetOrigin() const {
|
||||
return origin;
|
||||
}
|
||||
|
||||
Vector2 Entity::GetMotion() const {
|
||||
return motion;
|
||||
}
|
||||
|
||||
BoundingBox Entity::GetBounds() const {
|
||||
return bounds;
|
||||
}
|
||||
|
||||
const char* Entity::GetType() const {
|
||||
return type;
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 "bounding_box.hpp"
|
||||
#include "vector2.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
//The base class for all objects in the world
|
||||
class Entity {
|
||||
public:
|
||||
virtual void Update();
|
||||
|
||||
//accessors & mutators
|
||||
int SetRoomIndex(int i);
|
||||
Vector2 SetOrigin(Vector2 v);
|
||||
Vector2 SetMotion(Vector2 v);
|
||||
BoundingBox SetBounds(BoundingBox b);
|
||||
|
||||
int GetRoomIndex() const;
|
||||
Vector2 GetOrigin() const;
|
||||
Vector2 GetMotion() const;
|
||||
BoundingBox GetBounds() const;
|
||||
|
||||
const char* GetType() const;
|
||||
|
||||
protected:
|
||||
Entity(const char*);
|
||||
virtual ~Entity() = default;
|
||||
|
||||
int roomIndex = -1;
|
||||
Vector2 origin = {0, 0};
|
||||
Vector2 motion = {0, 0};
|
||||
BoundingBox bounds = {0, 0, 0, 0};
|
||||
const char* type;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,106 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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_api.hpp"
|
||||
|
||||
#include "entity.hpp"
|
||||
|
||||
static int setRoomIndex(lua_State* L) {
|
||||
Entity* entity = static_cast<Entity*>(lua_touserdata(L, 1));
|
||||
entity->SetRoomIndex(lua_tointeger(L, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setOrigin(lua_State* L) {
|
||||
Entity* entity = static_cast<Entity*>(lua_touserdata(L, 1));
|
||||
entity->SetOrigin({lua_tonumber(L, 2), lua_tonumber(L, 3)});
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setMotion(lua_State* L) {
|
||||
Entity* entity = static_cast<Entity*>(lua_touserdata(L, 1));
|
||||
entity->SetMotion({lua_tonumber(L, 2), lua_tonumber(L, 3)});
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setBounds(lua_State* L) {
|
||||
Entity* entity = static_cast<Entity*>(lua_touserdata(L, 1));
|
||||
entity->SetBounds({
|
||||
lua_tointeger(L, 2),
|
||||
lua_tointeger(L, 3),
|
||||
lua_tointeger(L, 4),
|
||||
lua_tointeger(L, 5)
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getRoomIndex(lua_State* L) {
|
||||
Entity* entity = static_cast<Entity*>(lua_touserdata(L, 1));
|
||||
lua_pushinteger(L, entity->GetRoomIndex());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int getOrigin(lua_State* L) {
|
||||
Entity* entity = static_cast<Entity*>(lua_touserdata(L, 1));
|
||||
lua_pushnumber(L, entity->GetOrigin().x);
|
||||
lua_pushnumber(L, entity->GetOrigin().y);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int getMotion(lua_State* L) {
|
||||
Entity* entity = static_cast<Entity*>(lua_touserdata(L, 1));
|
||||
lua_pushnumber(L, entity->GetMotion().x);
|
||||
lua_pushnumber(L, entity->GetMotion().y);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int getBounds(lua_State* L) {
|
||||
Entity* entity = static_cast<Entity*>(lua_touserdata(L, 1));
|
||||
lua_pushinteger(L, entity->GetBounds().x);
|
||||
lua_pushinteger(L, entity->GetBounds().y);
|
||||
lua_pushinteger(L, entity->GetBounds().w);
|
||||
lua_pushinteger(L, entity->GetBounds().h);
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int getType(lua_State* L) {
|
||||
Entity* entity = static_cast<Entity*>(lua_touserdata(L, 1));
|
||||
lua_pushstring(L, entity->GetType());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_Reg entityLib[] = {
|
||||
{"SetRoomIndex", setRoomIndex},
|
||||
{"SetOrigin", setOrigin},
|
||||
{"SetMotion", setMotion},
|
||||
{"SetBounds", setBounds},
|
||||
{"GetRoomIndex", getRoomIndex},
|
||||
{"GetOrigin", getOrigin},
|
||||
{"GetMotion", getMotion},
|
||||
{"GetBounds", getBounds},
|
||||
{"GetType", getType},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
||||
LUAMOD_API int openEntityAPI(lua_State* L) {
|
||||
luaL_newlib(L, entityLib);
|
||||
return 1;
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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 ENTITYAPI_HPP_
|
||||
#define ENTITYAPI_HPP_
|
||||
|
||||
#include "lua.hpp"
|
||||
|
||||
#define TORTUGA_ENTITY_API "entity"
|
||||
LUAMOD_API int openEntityAPI(lua_State* L);
|
||||
|
||||
#endif
|
||||
@@ -1,37 +0,0 @@
|
||||
#config
|
||||
INCLUDES+=. ../../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
|
||||
@@ -1,70 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
#include "server_application.hpp"
|
||||
|
||||
//singletons
|
||||
#include "account_manager.hpp"
|
||||
#include "character_manager.hpp"
|
||||
#include "client_manager.hpp"
|
||||
#include "config_utility.hpp"
|
||||
#include "room_manager.hpp"
|
||||
#include "udp_network_utility.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
try {
|
||||
//create the singletons
|
||||
AccountManager::CreateSingleton();
|
||||
CharacterManager::CreateSingleton();
|
||||
ClientManager::CreateSingleton();
|
||||
ConfigUtility::CreateSingleton();
|
||||
RoomManager::CreateSingleton();
|
||||
UDPNetworkUtility::CreateSingleton();
|
||||
|
||||
//call the server's routines
|
||||
ServerApplication::CreateSingleton();
|
||||
ServerApplication& app = ServerApplication::GetSingleton();
|
||||
|
||||
app.Init(argc, argv);
|
||||
app.Proc();
|
||||
app.Quit();
|
||||
|
||||
ServerApplication::DeleteSingleton();
|
||||
|
||||
//delete the singletons
|
||||
AccountManager::DeleteSingleton();
|
||||
CharacterManager::DeleteSingleton();
|
||||
ClientManager::DeleteSingleton();
|
||||
ConfigUtility::DeleteSingleton();
|
||||
RoomManager::DeleteSingleton();
|
||||
UDPNetworkUtility::DeleteSingleton();
|
||||
}
|
||||
catch(exception& e) {
|
||||
cerr << "Fatal exception thrown: " << e.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
#include directories
|
||||
INCLUDES+=. accounts characters clients entities monsters rooms server_utilities triggers ../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
|
||||
CXXSRC=$(wildcard *.cpp)
|
||||
|
||||
#objects
|
||||
OBJDIR=obj
|
||||
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
||||
|
||||
#output
|
||||
OUTDIR=../out
|
||||
OUT=$(addprefix $(OUTDIR)/,server)
|
||||
|
||||
#targets
|
||||
all: $(OBJ) $(OUT)
|
||||
$(MAKE) -C accounts
|
||||
$(MAKE) -C characters
|
||||
$(MAKE) -C clients
|
||||
$(MAKE) -C entities
|
||||
$(MAKE) -C monsters
|
||||
$(MAKE) -C rooms
|
||||
$(MAKE) -C server_utilities
|
||||
$(MAKE) -C triggers
|
||||
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
|
||||
|
||||
$(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
|
||||
@@ -1,37 +0,0 @@
|
||||
#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
|
||||
@@ -1,88 +0,0 @@
|
||||
/* Copyright: (c) Kayne Ruse 2013-2015
|
||||
*
|
||||
* 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_api.hpp"
|
||||
|
||||
#include "monster_data.hpp"
|
||||
|
||||
#include "entity_api.hpp"
|
||||
|
||||
static int setAvatar(lua_State* L) {
|
||||
MonsterData* monster = static_cast<MonsterData*>(lua_touserdata(L, 1));
|
||||
monster->SetAvatar(lua_tostring(L, 2));
|
||||
//TODO: send an update to the clients?
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getAvatar(lua_State* L) {
|
||||
MonsterData* monster = static_cast<MonsterData*>(lua_touserdata(L, 1));
|
||||
lua_pushstring(L, monster->GetAvatar().c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int setScript(lua_State* L) {
|
||||
MonsterData* monster = static_cast<MonsterData*>(lua_touserdata(L, 1));
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, monster->GetScriptReference());
|
||||
monster->SetScriptReference(luaL_ref(L, LUA_REGISTRYINDEX));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getScript(lua_State* L) {
|
||||
MonsterData* monster = static_cast<MonsterData*>(lua_touserdata(L, 1));
|
||||
lua_pushinteger(L, monster->GetScriptReference());
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_Reg monsterLib[] = {
|
||||
{"SetAvatar", setAvatar},
|
||||
{"GetAvatar", getAvatar},
|
||||
{"SetScript", setScript},
|
||||
{"GetScript", getScript},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
||||
LUAMOD_API int openMonsterAPI(lua_State* L) {
|
||||
//get the parent table
|
||||
luaL_requiref(L, TORTUGA_ENTITY_API, openEntityAPI, false);
|
||||
|
||||
//the local table
|
||||
luaL_newlib(L, monsterLib);
|
||||
|
||||
//merge the local table into the parent table
|
||||
lua_pushnil(L); //first key
|
||||
while(lua_next(L, -2)) {
|
||||
//copy the key-value pair
|
||||
lua_pushvalue(L, -2);
|
||||
lua_pushvalue(L, -2);
|
||||
|
||||
//push the copy to the parent table
|
||||
lua_settable(L, -6);
|
||||
|
||||
//pop the original value before continuing
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
//remove the local table, leaving the expanded parent table
|
||||
lua_pop(L, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user