Merge branch 'drunk'

This commit is contained in:
2016-12-09 22:50:39 +11:00
24 changed files with 289 additions and 224 deletions
+4
View File
@@ -103,3 +103,7 @@ void BaseScene::KeyDown(SDL_KeyboardEvent const& event) {
void BaseScene::KeyUp(SDL_KeyboardEvent const& event) {
//EMPTY
}
void BaseScene::TextInput(SDL_TextInputEvent const& event) {
//EMPTY
}
+2 -1
View File
@@ -47,8 +47,9 @@ public:
virtual void MouseWheel(SDL_MouseWheelEvent const& event);
virtual void KeyDown(SDL_KeyboardEvent const& event);
virtual void KeyUp(SDL_KeyboardEvent const& event);
virtual void TextInput(SDL_TextInputEvent const& event);
//TODO: (9) joystick and controller events
//TODO: joystick and controller events
protected:
//control
+10
View File
@@ -188,6 +188,12 @@ void ClientApplication::Init(int argc, char* argv[]) {
DEBUG_INTERNAL_VAR(MAX_PACKET_SIZE);
DEBUG_INTERNAL_VAR(static_cast<int>(SerialPacketType::LAST));
//-------------------------
//BUGFIX
//-------------------------
SDL_StopTextInput();
//-------------------------
//finalize the startup
//-------------------------
@@ -298,6 +304,10 @@ void ClientApplication::ProcessEvents() {
activeScene->KeyUp(event.key);
break;
case SDL_TEXTINPUT:
activeScene->TextInput(event.text);
break;
//TODO: (9) joystick and controller events
//window events are handled internally
+108 -8
View File
@@ -68,6 +68,26 @@ LobbyMenu::LobbyMenu(int* const argClientIndex, int* const argAccountIndex):
backButton.SetX(50);
backButton.SetY(90);
//setup the text fields
username.SetText(GetRenderer(), font, WHITE, config["client.username"]);
password.SetText(GetRenderer(), font, WHITE, config["client.password"]);
handle.SetText(GetRenderer(), font, WHITE, config["client.handle"]);
avatar.SetText(GetRenderer(), font, WHITE, config["client.avatar"]);
username.SetBounds(BoundingBox{0, 0, 300, 20});
password.SetBounds(BoundingBox{0, 0, 300, 20});
handle.SetBounds(BoundingBox{0, 0, 300, 20});
avatar.SetBounds(BoundingBox{0, 0, 300, 20});
username.SetX(50);
username.SetY(110);
password.SetX(50);
password.SetY(130);
handle.SetX(50);
handle.SetY(150);
avatar.SetX(50);
avatar.SetY(170);
//pseudo-list selection
//TODO: move this into the UI library?
boundingBox = {300, 50, 200, 12};
@@ -115,6 +135,11 @@ void LobbyMenu::RenderFrame(SDL_Renderer* renderer) {
joinButton.DrawTo(renderer);
backButton.DrawTo(renderer);
username.DrawTo(renderer);
password.DrawTo(renderer);
handle.DrawTo(renderer);
avatar.DrawTo(renderer);
//TODO: (3) draw headers for the server list
//TODO: (3) ping/delay displayed in the server list
for (int i = 0; i < serverVector.size(); i++) {
@@ -148,6 +173,35 @@ void LobbyMenu::MouseButtonDown(SDL_MouseButtonEvent const& event) {
searchButton.MouseButtonDown(event);
joinButton.MouseButtonDown(event);
backButton.MouseButtonDown(event);
if (username.MouseButtonDown(event)) {
//GUI trick
if (!username.GetText().compare(config["client.username"])) {
username.SetText(GetRenderer(), font, WHITE, "");
}
SDL_StartTextInput();
}
if (password.MouseButtonDown(event)) {
//GUI trick
if (!password.GetText().compare(config["client.password"])) {
password.SetText(GetRenderer(), font, WHITE, "");
}
SDL_StartTextInput();
}
if (handle.MouseButtonDown(event)) {
//GUI trick
if (!handle.GetText().compare(config["client.handle"])) {
handle.SetText(GetRenderer(), font, WHITE, "");
}
SDL_StartTextInput();
}
if (avatar.MouseButtonDown(event)) {
//GUI trick
if (!avatar.GetText().compare(config["client.avatar"])) {
avatar.SetText(GetRenderer(), font, WHITE, "");
}
SDL_StartTextInput();
}
}
void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& event) {
@@ -182,6 +236,22 @@ void LobbyMenu::KeyDown(SDL_KeyboardEvent const& event) {
case SDLK_ESCAPE:
SetSceneSignal(SceneSignal::MAINMENU);
break;
case SDLK_BACKSPACE:
//easier than mucking about with SDL_TextEditEvent
if (username.GetFocus()) {
username.PopChars(GetRenderer(), font, WHITE, 1);
}
if (password.GetFocus()) {
password.PopChars(GetRenderer(), font, WHITE, 1);
}
if (handle.GetFocus()) {
handle.PopChars(GetRenderer(), font, WHITE, 1);
}
if (avatar.GetFocus()) {
avatar.PopChars(GetRenderer(), font, WHITE, 1);
}
break;
}
}
@@ -189,6 +259,21 @@ void LobbyMenu::KeyUp(SDL_KeyboardEvent const& event) {
//
}
void LobbyMenu::TextInput(SDL_TextInputEvent const& event) {
if (username.GetFocus()) {
username.PushText(GetRenderer(), font, WHITE, std::string(event.text));
}
if (password.GetFocus()) {
password.PushText(GetRenderer(), font, WHITE, std::string(event.text));
}
if (handle.GetFocus()) {
handle.PushText(GetRenderer(), font, WHITE, std::string(event.text));
}
if (avatar.GetFocus()) {
avatar.PushText(GetRenderer(), font, WHITE, std::string(event.text));
}
}
//-------------------------
//Network handlers
//-------------------------
@@ -278,11 +363,19 @@ void LobbyMenu::HandleLoginResponse(ClientPacket* const argPacket) {
}
void LobbyMenu::HandleJoinRejection(TextPacket* const argPacket) {
//TODO: (9) LobbyMenu::HandleJoinRejection()
//NOTE: NEVER HAPPENS
throw(std::runtime_error("HandleJoinRejection"));
}
void LobbyMenu::HandleLoginRejection(TextPacket* const argPacket) {
//TODO: (9) LobbyMenu::HandleLoginRejection
config["client.disconnectMessage"] = std::string() + "Join request rejected: " + argPacket->text;
SetSceneSignal(SceneSignal::DISCONNECTEDSCREEN);
//avoid crashes from the heartbeat system
ClientPacket newPacket;
newPacket.type = SerialPacketType::DISCONNECT_REQUEST;
newPacket.clientIndex = clientIndex;
network.SendTo(argPacket->srcAddress, &newPacket);
}
//-------------------------
@@ -303,13 +396,14 @@ void LobbyMenu::SendBroadcastRequest() {
}
void LobbyMenu::SendJoinRequest() {
//BUG: 101 received in LobbyMenu on failed join
//pack the packet
ClientPacket packet;
packet.type = SerialPacketType::JOIN_REQUEST;
ClientPacket packet;
packet.type = SerialPacketType::JOIN_REQUEST;
//join the selected server
network.SendTo(selection->address, &packet);
selection = nullptr;
//join the selected server
network.SendTo(selection->address, &packet);
selection = nullptr;
}
void LobbyMenu::SendLoginRequest() {
@@ -318,7 +412,13 @@ void LobbyMenu::SendLoginRequest() {
ClientPacket packet;
packet.type = SerialPacketType::LOGIN_REQUEST;
packet.clientIndex = clientIndex;
strncpy(packet.username, config["client.username"].c_str(), PACKET_STRING_SIZE+1);
strncpy(packet.username, username.GetText().c_str(), PACKET_STRING_SIZE+1);
network.SendTo(Channels::SERVER, &packet);
//TODO: remove
config["client.username"] = username.GetText();
config["client.password"] = password.GetText();
config["client.handle"] = handle.GetText();
config["client.avatar"] = avatar.GetText();
}
+6
View File
@@ -25,6 +25,7 @@
#include "image.hpp"
#include "button.hpp"
#include "bounding_box.hpp"
#include "text_field.hpp"
#include "text_line.hpp"
#include "SDL2/SDL_ttf.h"
@@ -61,6 +62,7 @@ protected:
void MouseWheel(SDL_MouseWheelEvent const& event) override;
void KeyDown(SDL_KeyboardEvent const& event) override;
void KeyUp(SDL_KeyboardEvent const& event) override;
void TextInput(SDL_TextInputEvent const& event) override;
//Network handlers
void HandlePacket(SerialPacket* const);
@@ -102,6 +104,10 @@ protected:
Button searchButton;
Button joinButton;
Button backButton;
TextField username;
TextField password;
TextField handle;
TextField avatar;
std::vector<ServerInfo> serverVector;
ServerInfo* selection = nullptr;
+17 -2
View File
@@ -154,7 +154,7 @@ void World::Update() {
throw(e);
}
catch(std::exception& e) {
std::cerr << "HandlePacket Error: " << e.what() << std::endl;
std::cerr << "HandlePacket Error (" << (int)(reinterpret_cast<SerialPacket*>(packetBuffer)->type) << "): " << e.what() << std::endl;
}
//free the buffer
@@ -458,6 +458,10 @@ void World::HandlePacket(SerialPacket* const argPacket) {
hCharacterMovement(static_cast<CharacterPacket*>(argPacket));
break;
case SerialPacketType::CHARACTER_REJECTION:
hCharacterRejection(static_cast<TextPacket*>(argPacket));
break;
//creature management
case SerialPacketType::CREATURE_UPDATE:
hCreatureUpdate(static_cast<CreaturePacket*>(argPacket));
@@ -507,7 +511,6 @@ void World::HandlePacket(SerialPacket* const argPacket) {
//general rejection messages
case SerialPacketType::REGION_REJECTION:
case SerialPacketType::CHARACTER_REJECTION:
case SerialPacketType::QUERY_REJECTION:
throw(fatal_error(static_cast<TextPacket*>(argPacket)->text));
break;
@@ -810,6 +813,18 @@ void World::hCharacterMovement(CharacterPacket* const argPacket) {
}
}
void World::hCharacterRejection(TextPacket* const argPacket) {
//NOTE: simply crap out
config["client.disconnectMessage"] = std::string() + "Character rejected: " + argPacket->text;
SetSceneSignal(SceneSignal::DISCONNECTEDSCREEN);
//avoid crashes from the heartbeat system
ClientPacket newPacket;
newPacket.type = SerialPacketType::DISCONNECT_REQUEST;
newPacket.clientIndex = clientIndex;
network.SendTo(argPacket->srcAddress, &newPacket);
}
//-------------------------
//creature management
//-------------------------
+1
View File
@@ -102,6 +102,7 @@ private:
void hCharacterUnload(CharacterPacket* const);
void hQueryCharacterExists(CharacterPacket* const);
void hCharacterMovement(CharacterPacket* const);
void hCharacterRejection(TextPacket* const);
//creature management
void hCreatureUpdate(CreaturePacket* const);
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. packet_types ../global_defines ../utilities ../../TurtleMap
INCLUDES+=. packet_types ../global_defines ../utilities ../../TurtleGUI ../../TurtleMap
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. .. ../../global_defines ../../utilities ../../../TurtleMap
INCLUDES+=. .. ../../global_defines ../../utilities ../../../TurtleGUI ../../../TurtleMap
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+1 -1
View File
@@ -34,7 +34,7 @@
typedef SerialPacketBase SerialPacket;
//DOCS: NETWORK_VERSION is used to discern compatible servers and clients
constexpr int NETWORK_VERSION = 20160825;
constexpr int NETWORK_VERSION = 20161209;
union MaxPacket {
BarrierPacket a;
-75
View File
@@ -1,75 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* 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.
*/
#pragma once
#include <type_traits>
#include <algorithm>
class BoundingBox {
public:
//This is explicitly a POD
int x, y;
int w, h;
BoundingBox() = default;
BoundingBox(int i, int j): x(i), y(j), w(0), h(0) {};
BoundingBox(int i, int j, int k, int l): x(i), y(j), w(k), h(l) {};
~BoundingBox() = default;
BoundingBox& operator=(BoundingBox const&) = default;
int Size() {
return std::max(w*h,0);
}
bool CheckOverlap(BoundingBox rhs) {
return !(
x >= rhs.x + rhs.w ||
y >= rhs.y + rhs.h ||
rhs.x >= x + w ||
rhs.y >= y + h);
}
BoundingBox CalcOverlap(BoundingBox rhs) {
if (!CheckOverlap(rhs)) {
return {0, 0, 0, 0};
}
BoundingBox ret;
ret.x = std::max(x, rhs.x);
ret.y = std::max(y, rhs.y);
ret.w = std::min(x+w, rhs.x+rhs.w) - ret.x;
ret.h = std::min(y+h, rhs.y+rhs.h) - ret.y;
return ret;
}
};
//This is explicitly a POD
static_assert(std::is_pod<BoundingBox>::value, "BoundingBox is not a POD");
#include "vector2.hpp"
//operators
inline BoundingBox operator+(BoundingBox b, Vector2 v) {
return {b.x + (int)v.x, b.y + (int)v.y, b.w, b.h};
}
inline BoundingBox operator+(Vector2 v, BoundingBox b) {
return b + v;
}
+60
View File
@@ -0,0 +1,60 @@
/* Copyright: (c) Kayne Ruse 2016
*
* 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 "file_hash.hpp"
#include <fstream>
//hash a byte array into a 32-bit integer
unsigned fnv_hash_1a_32(void *key, int len) {
unsigned char *p = static_cast<unsigned char*>(key);
unsigned h = 0x811c9dc5;
for (int i = 0; i < len; i++) {
h = ( h ^ p[i] ) * 0x01000193;
}
return h;
}
int getFileHash(std::string fname) {
std::ifstream is(fname, std::ios::in | std::ios::binary);
//if the file doesn't exist, return a hash of -1
if (!is.is_open()) {
return -1;
}
//get the file size
is.seekg(0, std::ios_base::end);
int size = is.tellg();
is.seekg(0);
//create a buffer of that size
char buffer[size];
//load the data
is.read(buffer, size);
//cleanup
is.close();
//finally, return the hash value
return fnv_hash_1a_32(buffer, size);
}
+26
View File
@@ -0,0 +1,26 @@
/* Copyright: (c) Kayne Ruse 2016
*
* 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.
*/
#pragma once
#include <string>
int getFileHash(std::string fname);
-111
View File
@@ -1,111 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* 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.
*/
#pragma once
#include <type_traits>
#include <stdexcept>
#include <cmath>
class Vector2 {
public:
double x, y;
Vector2() = default;
Vector2(double i, double j): x(i), y(j) {};
~Vector2() = default;
Vector2& operator=(Vector2 const&) = default;
double Length() const {
return sqrt(x*x+y*y);
}
double SquaredLength() const {
return x*x+y*y;
}
void Normalize() {
double l = Length();
if (l == 0)
throw(std::domain_error("Divide by zero"));
x /= l;
y /= l;
}
//Arithmetic operators
Vector2 operator+(Vector2 v) const {
Vector2 ret;
ret.x = x + v.x;
ret.y = y + v.y;
return ret;
}
Vector2 operator-(Vector2 v) const {
Vector2 ret;
ret.x = x - v.x;
ret.y = y - v.y;
return ret;
}
Vector2 operator*(Vector2 v) const {
Vector2 ret;
ret.x = x * v.x;
ret.y = y * v.y;
return ret;
}
Vector2 operator*(double d) const {
Vector2 ret;
ret.x = x * d;
ret.y = y * d;
return ret;
}
Vector2 operator/(Vector2 v) {
if (!v.x || !v.y)
throw(std::domain_error("Divide by zero"));
Vector2 ret;
ret.x = x / v.x;
ret.y = y / v.y;
return ret;
}
Vector2 operator/(double d) {
if (!d)
throw(std::domain_error("Divide by zero"));
Vector2 ret;
ret.x = x / d;
ret.y = y / d;
return ret;
}
//unary operators
Vector2 operator-() { return {-x, -y}; }
//comparison operators
bool operator==(Vector2 v) { return (x == v.x && y == v.y); }
bool operator!=(Vector2 v) { return (x != v.x || y != v.y); }
//member templates (curry the above operators)
template<typename T> Vector2 operator+=(T t) { return *this = *this + t; }
template<typename T> Vector2 operator-=(T t) { return *this = *this - t; }
template<typename T> Vector2 operator*=(T t) { return *this = *this * t; }
template<typename T> Vector2 operator/=(T t) { return *this = *this / t; }
template<typename T> bool operator==(T t) { return (x == t && y == t); }
template<typename T> bool operator!=(T t) { return (x != t || y != t); }
};
//This is explicitly a POD
static_assert(std::is_pod<Vector2>::value, "Vector2 is not a POD");
+8 -16
View File
@@ -15,24 +15,16 @@ 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:
(a public server "Island Home" is provided by default)
2. To play, run client.exe
3. Your unique information should be inputted into the lobby screen, replacing
the default values.
4. There are currently two options for avatars:
* client.username
* client.handle
* character1.png #male
* character2.png #female
5. There are currently two options for 'client.avatar':
* client.avatar = character1.png #male
* client.avatar = character2.png #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.
5. Select a server, and click join.
-------------------------
Linux Users
+1
View File
@@ -15,6 +15,7 @@ server.dbname = database.db
#client.screen.f = false #NOTE: fullscreen option is currently disabled
client.username = username
client.password = password
client.handle = handle
client.avatar = character2.png
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. .. ../characters ../creatures ../entities ../inventory ../../common/global_defines ../../common/utilities
INCLUDES+=. .. ../characters ../creatures ../entities ../inventory ../../common/global_defines ../../common/utilities ../../TurtleGUI
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. .. ../characters ../creatures ../entities ../inventory ../../common/global_defines ../../common/utilities
INCLUDES+=. .. ../characters ../creatures ../entities ../inventory ../../common/global_defines ../../common/utilities ../../TurtleGUI
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. .. ../barriers ../battles ../creatures ../entities ../monsters ../inventory ../rooms ../triggers ../../common/global_defines ../../common/network ../../common/network/packet_types ../../common/utilities ../../TurtleMap
INCLUDES+=. .. ../barriers ../battles ../creatures ../entities ../monsters ../inventory ../rooms ../triggers ../../common/global_defines ../../common/network ../../common/network/packet_types ../../common/utilities ../../TurtleGUI ../../TurtleMap
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. .. ../entities ../../common/global_defines ../../common/utilities
INCLUDES+=. .. ../entities ../../common/global_defines ../../common/utilities ../../TurtleGUI
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. ../../common/utilities
INCLUDES+=. ../../common/utilities ../../TurtleGUI
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. .. ../barriers ../battles ../characters ../creatures ../entities ../inventory ../monsters ../triggers ../../common/global_defines ../../common/network ../../common/network/packet_types ../../common/utilities ../../TurtleMap
INCLUDES+=. .. ../barriers ../battles ../characters ../creatures ../entities ../inventory ../monsters ../triggers ../../common/global_defines ../../common/network ../../common/network/packet_types ../../common/utilities ../../TurtleGUI ../../TurtleMap
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+36 -1
View File
@@ -22,6 +22,7 @@
#include "server_application.hpp"
//utility functions
#include "file_hash.hpp"
#include "sql_tools.hpp"
//std & STL
@@ -181,7 +182,7 @@ void ServerApplication::Proc() {
HandlePacket(packetBuffer);
}
catch(std::exception& e) {
std::cerr << "HandlePacket Error: " << e.what() << std::endl;
std::cerr << "HandlePacket Error (" << (int)(packetBuffer->type) << "): " << e.what() << std::endl;
}
//reset the buffer
memset(packetBuffer, 0, MAX_PACKET_SIZE);
@@ -607,8 +608,25 @@ void ServerApplication::hQueryCharacterExists(CharacterPacket* const argPacket)
}
void ServerApplication::hCharacterCreate(CharacterPacket* const argPacket) {
//check to see of the character's files are valid
if (getFileHash(config["dir.sprites"] + argPacket->avatar) == -1) {
//build the error message
std::ostringstream msg;
msg << "Character avatar is invalid on this server: " << argPacket->avatar;
//build & send the packet
TextPacket newPacket;
newPacket.type = SerialPacketType::CHARACTER_REJECTION;
strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE);
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
return;
}
//create the character
int characterIndex = characterMgr.Create(argPacket->accountIndex, argPacket->handle, argPacket->avatar);
//check to see of the character already exists
if (characterIndex < 0) {
//build the error message
std::ostringstream msg;
@@ -683,8 +701,25 @@ void ServerApplication::hCharacterDelete(CharacterPacket* const argPacket) {
}
void ServerApplication::hCharacterLoad(CharacterPacket* const argPacket) {
//check to see of the character's files are valid
if (getFileHash(config["dir.sprites"] + argPacket->avatar) == -1) {
//build the error message
std::ostringstream msg;
msg << "Character avatar is invalid on this server: " << argPacket->avatar;
//build & send the packet
TextPacket newPacket;
newPacket.type = SerialPacketType::CHARACTER_REJECTION;
strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE);
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
return;
}
//load the character
int characterIndex = characterMgr.Load(argPacket->accountIndex, argPacket->handle, argPacket->avatar);
//check to see if the character is already loaded
if (characterIndex < 0) {
//build the error message
std::ostringstream msg;
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. .. ../entities ../../common/utilities
INCLUDES+=. .. ../entities ../../common/utilities ../../TurtleGUI
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))