From e18fa1d8ad9208a9f5bcfe2d97d36ae3675c80f1 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 10 Jul 2011 19:31:42 +0000 Subject: Generate a player ID when connecting to a server, read it from keys.ini if it was previously generated. --- src/core/Makefile.am | 2 + src/core/gameconnection.cc | 71 ++++++++++++++++------- src/core/player.cc | 5 -- src/core/player.h | 5 +- src/core/uid.cc | 141 +++++++++++++++++++++++++++++++++++++++++++++ src/core/uid.h | 72 +++++++++++++++++++++++ 6 files changed, 268 insertions(+), 28 deletions(-) create mode 100644 src/core/uid.cc create mode 100644 src/core/uid.h (limited to 'src') diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 4f5011c..0c8036e 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -32,6 +32,7 @@ noinst_HEADERS = \ range.h \ signals.h \ stats.h \ + uid.h \ zone.h libcore_la_SOURCES = \ @@ -60,6 +61,7 @@ libcore_la_SOURCES = \ player.cc \ signals.cc \ stats.cc \ + uid.cc \ zone.cc libcore_la_DEPENDENCIES = \ diff --git a/src/core/gameconnection.cc b/src/core/gameconnection.cc index ebd5a49..a62fb4f 100644 --- a/src/core/gameconnection.cc +++ b/src/core/gameconnection.cc @@ -24,7 +24,56 @@ GameConnection::GameConnection(std::string const &connectionstr) connection_instance = this; connection_network = 0; connection_netframe = 0; + + // clear current guid + localplayer()->guid().clear(); + + // read keys.ini + std::string filename(filesystem::homedir()); + filename.append("keys.ini"); + + std::ifstream ifs(filename.c_str()); + if (ifs.is_open()) { + filesystem::IniStream inistr; + + while(inistr.getline(ifs)) { + if (inistr.in_section("client")) { + std::string s; + if (inistr.got_key_string("key", s)) { + aux::to_lowercase(s); + aux::trim(s); + localplayer()->guid().assign(s); + if (!localplayer()->guid().is_valid()) { + con_warn << "keys.ini invalid client key '" << s << "' at line " << inistr.line() << std::endl; + + } + } + } + } + + ifs.close(); + } + // if no valid key was found, generate one + if (!localplayer()->guid().is_valid()) { + localplayer()->guid().generate(); + } + + // write keys.ini + std::ofstream ofs(filename.c_str()); + if (!ofs.is_open()) { + con_warn << "Could not write " << filename << std::endl; + } else { + ofs << "; keys.ini - osirion client identification" << std::endl; + ofs << "; DO NOT EDIT OR DELETE THIS FILE" << std::endl; + ofs << "; If you do, you will not be able to use existing characters in multiplayer games" << std::endl; + ofs << std::endl; + ofs << "[client]" << std::endl; + ofs << "key=" << localplayer()->guid().str() << std::endl; + ofs.close(); + } + + // split hostname into host and port unsigned int port = DEFAULTPORT; std::string host(connectionstr); size_t found = host.find(':'); @@ -41,6 +90,7 @@ GameConnection::GameConnection(std::string const &connectionstr) } + // initiate the network connection connection_network = new NetConnection(); connection_network->connect(host, port); @@ -61,27 +111,6 @@ GameConnection::GameConnection(std::string const &connectionstr) game_players.push_back(localplayer()); set_playerlist_timestamp(timestamp()); - // generate player GUID - // we do it here because offline play doesn't require it - if (!localplayer()->guid().size()) { - - // read keys.ini - - // write keys.ini - std::string filename(filesystem::homedir()); - filename.append("keys.ini"); - - std::ofstream ofs(filename.c_str()); - if (!ofs.is_open()) { - con_warn << "Could not write " << filename << std::endl; - } else { - ofs << "; keys.ini - osirion client identification" << std::endl; - ofs << "; DO NOT EDIT OR DELETE THIS FILE" << std::endl; - ofs << "; If you do you will not be able to use existing characters on a remote server" << std::endl; - ofs.close(); - } - } - set_interactive(true); set_running(true); } diff --git a/src/core/player.cc b/src/core/player.cc index d07b258..87640ac 100644 --- a/src/core/player.cc +++ b/src/core/player.cc @@ -141,11 +141,6 @@ void Player::set_admin_level(const int admin_level) player_admin_level = admin_level; } -void Player::set_guid(const std::string & guid) -{ - player_guid.assign(guid); -} - void Player::update_info() { Cvar *cl_name = Cvar::find("cl_name"); diff --git a/src/core/player.h b/src/core/player.h index afd1bc9..117de56 100644 --- a/src/core/player.h +++ b/src/core/player.h @@ -14,6 +14,7 @@ class Player; #include "core/entity.h" #include "core/message.h" +#include "core/uid.h" #include "core/zone.h" #include "core/netclient.h" #include "math/mathlib.h" @@ -126,7 +127,7 @@ public: } /// player global unique id - const std::string & guid() const { + UID & guid() { return player_guid; } @@ -273,7 +274,7 @@ private: int player_admin_level; // global unique id - std::string player_guid; + UID player_guid; // dirty bit bool player_dirty; diff --git a/src/core/uid.cc b/src/core/uid.cc new file mode 100644 index 0000000..c33e465 --- /dev/null +++ b/src/core/uid.cc @@ -0,0 +1,141 @@ +/* + core/uid.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2. +*/ + +// #include +#include "sys/sys.h" +#include "core/uid.h" +#include "math/functions.h" + +#include + +namespace core +{ + +const char hexchar[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; + +UID::UID() +{ + clear(); +} + +UID::~UID() +{ + clear(); +} + +UID::UID(const UID & other) +{ + assign(other); +} + +void UID::assign(const UID & other) +{ + memcpy(uid_key, other.uid_key, UIDKEYSIZE); +} + +void UID::assign(const std::string & str) +{ + char new_key[UIDKEYSIZE]; + char l, h; + + if (str.size() != UIDKEYSIZE * 2) { + return; + } + + for (size_t i = 0; i < UIDKEYSIZE; i++ ) { + h = str[i * 2]; + switch (h) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + new_key[i] = (h - '0') << 4; + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + new_key[i] = (h - 'a' + 10) << 4; + break; + default: + return; + break; + } + + l = str[i * 2 + 1]; + switch (l) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + new_key[i] += (l - '0'); + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + new_key[i] += (l - 'a' + 10); + break; + default: + return; + break; + } + } + + memcpy(uid_key, new_key, UIDKEYSIZE); +} + +void UID::generate() +{ + for (size_t i = 0; i < UIDKEYSIZE; i++) { + // FIXME the worst random key generator ever + uid_key[i] = math::randomi(256); + } +} + +bool UID::is_valid() const +{ + for (size_t i = 0; i < UIDKEYSIZE; i++) { + if (uid_key[i] != 0 ) + return true; + } + return false; +} + +void UID::clear() +{ + memset(uid_key, 0, UIDKEYSIZE); +} + +const std::string UID::str() const { + std::string s; + for (size_t i = 0; i < UIDKEYSIZE; i++) { + // upper nibble + s += hexchar[ uid_key[i] >> 4 ]; + // lower nibble + s += hexchar[ uid_key[i] % 16 ]; + } + return s; +} + + +} // namespace core diff --git a/src/core/uid.h b/src/core/uid.h new file mode 100644 index 0000000..1954852 --- /dev/null +++ b/src/core/uid.h @@ -0,0 +1,72 @@ +/* + core/uid.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2. +*/ + +#ifndef __INCLUDED_CORE_UID_H__ +#define __INCLUDED_CORE_UID_H__ + +#include + +namespace core +{ + +const size_t UIDKEYSIZE = 16; + +class UID { +public: + /** + * @brief default constructor + * will contain a zero-valued uid + */ + UID(); + + /** + * @brief copy constructor + */ + UID(const UID & other); + + /** + * @brief destructor + */ + ~UID(); + + /** + * return a strin representation of the key + */ + const std::string str() const; + + /* ---- mutators ------------------------------------------- */ + + /** + * @brief assign another UID + */ + void assign(const UID & other); + + /** + * @brief assign UID from a string + */ + void assign(const std::string & str); + + /** + * @brief generate a random UID + */ + void generate(); + + /** + * @brief reset UID to 0 + */ + void clear(); + + bool is_valid() const; + +private: + unsigned char uid_key[UIDKEYSIZE]; +}; + +} // namespace core + +#endif // __INCLUDED_CORE_UID_H__ + + \ No newline at end of file -- cgit v1.2.3