00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "srv-converse.h"
00035
00036 #include "srv-hosts.h"
00037 #include "srv-msg-router.h"
00038 #include "srv-users.h"
00039
00040 #include "common/wave_ex.h"
00041 #include "crypto/crypto.h"
00042 #include "datahash/datahash_util.h"
00043 #include "dialog/request.h"
00044 #include "perf/perf.h"
00045
00046
00047 namespace aesop {
00048
00049
00050
00051 enum eDialogs {
00052 eDialog_First = 1,
00053 eDialog_SignIn = 2,
00054 eDialog_Create = 3,
00055 eDialog_Fail = 4,
00056
00057
00058 eDialog_Done = 0
00059 };
00060
00061
00062
00064
00065
00066
00067
00069
00070 class NPHost : public converse::ConversationHost {
00071 public:
00072 NPHost(void) throw();
00073 ~NPHost(void) throw() { }
00074
00075
00076 void initialize(IN smart_ptr<crypto::DESKey>& desKey,
00077 IN new_player_conv_data_t& data);
00078
00079
00080 int getCurrentDialogIdTS(void);
00081 void handleReplyTS(IN int dialogId,
00082 IN const Datahash * reply);
00083 std::string getDialogDataTS(void);
00084
00085 private:
00086
00087
00088
00089 smart_ptr<crypto::DESKey> m_desKey;
00090 new_player_conv_data_t m_data;
00091 int m_dialog;
00092 std::string m_header;
00093 std::string m_username;
00094 std::string m_diagnostic;
00095 };
00096
00097
00098
00099 NPHost::NPHost(void)
00100 throw()
00101 {
00102 m_dialog = eDialog_First;
00103 }
00104
00105
00106
00107 void
00108 NPHost::initialize
00109 (
00110 IN smart_ptr<crypto::DESKey>& desKey,
00111 IN new_player_conv_data_t& data
00112 )
00113 {
00114 ASSERT(desKey, "null");
00115 ASSERT(data.isValid(), "invalid new player data");
00116
00117 ASSERT(!m_desKey, "Already have symmetric encryption key?");
00118 m_desKey = desKey;
00119
00120 m_data = data;
00121 ASSERT(m_data.isValid(), "copied data is invalid?");
00122
00123
00124 const int bufSize = 64;
00125 char buffer[bufSize];
00126 gethostname(buffer, bufSize - 1);
00127 buffer[bufSize - 1] = 0;
00128
00129 m_header = "Server: ";
00130 m_header += buffer;
00131 }
00132
00133
00134
00136
00137
00138
00140
00141 int
00142 NPHost::getCurrentDialogIdTS
00143 (
00144 void
00145 )
00146 {
00147 return m_dialog;
00148 }
00149
00150
00151
00152 void
00153 NPHost::handleReplyTS
00154 (
00155 IN int dialogId,
00156 IN const Datahash * reply
00157 )
00158 {
00159 ASSERT(dialogId > 0, "Bad dialog id: %d", dialogId);
00160 ASSERT(reply, "null");
00161 ASSERT(m_data.isValid(), "invalid new player data");
00162
00163 std::string submit = getString(reply, "submit");
00164 DPRINTF("Received submit='%s' for dialog=%d", submit.c_str(), dialogId);
00165 std::string password;
00166
00167 if (dialogId != m_dialog) {
00168
00169
00170 DPRINTF("ERROR: called on wrong dialog id?");
00171 return;
00172 }
00173
00174
00175 if (eDialog_First == m_dialog) {
00176 if ("_new" == submit) {
00177 m_dialog = eDialog_Create;
00178 } else {
00179 m_username = submit;
00180
00181 if (m_data.userMgr->passwordRequiredTS()) {
00182 m_dialog = eDialog_SignIn;
00183 } else {
00184 m_dialog = eDialog_Done;
00185 }
00186 }
00187 } else if (eDialog_SignIn == m_dialog) {
00188 std::string enc = getString(reply, "password");
00189
00190 password = m_desKey->decrypt(enc.c_str());
00191 m_dialog = eDialog_Done;
00192 } else if (eDialog_Create == m_dialog) {
00193 std::string username = getString(reply, "username");
00194 if (m_data.userMgr->createUserTS(username.c_str(), m_diagnostic)) {
00195
00196 m_username = username;
00197 if (m_data.userMgr->passwordRequiredTS()) {
00198 m_dialog = eDialog_SignIn;
00199 } else {
00200 m_dialog = eDialog_Done;
00201 }
00202 } else {
00203
00204 DPRINTF("Failed: %s", m_diagnostic.c_str());
00205 m_dialog = eDialog_Fail;
00206 }
00207 } else if (eDialog_Fail == m_dialog) {
00208
00209 m_dialog = eDialog_First;
00210 } else {
00211 m_dialog = eDialog_Done;
00212 }
00213
00214
00215 if (eDialog_Done == m_dialog) {
00216
00217 std::string playerGuid;
00218 if (!m_data.userMgr->logInAsUserTS(m_username.c_str(),
00219 password.c_str(), playerGuid, m_diagnostic)) {
00220 DPRINTF("Failed! %s", m_diagnostic.c_str());
00221 m_dialog = eDialog_Fail;
00222 } else {
00223
00224 DPRINTF("Player guid: '%s'", playerGuid.c_str());
00225
00226
00227 if (!m_data.updates->setPlayerUserAccountTS(
00228 m_data.connId, m_data.playerId, m_username.c_str(),
00229 playerGuid.c_str(), m_diagnostic)) {
00230 DPRINTF("Server disallowed: %s",
00231 m_diagnostic.c_str());
00232 m_dialog = eDialog_Fail;
00233 }
00234 }
00235 }
00236 }
00237
00238
00239
00240 std::string
00241 NPHost::getDialogDataTS
00242 (
00243 void
00244 )
00245 {
00246 ASSERT(m_data.isValid(), "invalid new player data");
00247
00248
00249 if (eDialog_Done == m_dialog)
00250 return "";
00251
00252 dialog::ContainerRequest c;
00253 c.addLabel(m_header.c_str());
00254 if (eDialog_First == m_dialog) {
00255 c.addLabel("Select a user account");
00256 SetString names;
00257 m_data.userMgr->getUsernamesTS(names);
00258 for (SetString::iterator i = names.begin(); i != names.end();
00259 ++i) {
00260 const char * login = i->c_str();
00261 c.addButton(login, login);
00262 }
00263 if (m_data.userMgr->canCreateNewUsersTS()) {
00264 c.addButton("_new", "New User");
00265 }
00266 } else if (eDialog_SignIn == m_dialog) {
00267 std::string text = "Provide password for ";
00268 text += m_username;
00269 c.addLabel(text.c_str());
00270 c.addTextbox("password", "", 8, true);
00271 } else if (eDialog_Create == m_dialog) {
00272 c.addLabel("Provide new username");
00273 c.addTextbox("username", "", 8);
00274 } else if (eDialog_Fail == m_dialog) {
00275 std::string error = "Error: ";
00276 error += m_diagnostic;
00277 c.addLabel(error.c_str());
00278 c.addButton("retry", "Retry");
00279 } else {
00280 ASSERT(false, "bad dialog id? %d", m_dialog);
00281 }
00282
00283 return c.get();
00284 }
00285
00286
00287
00288
00290
00291
00292
00294
00295
00297
00298
00299
00301
00302 smart_ptr<converse::ConversationHost>
00303 createNewPlayerConversationHost
00304 (
00305 IN smart_ptr<crypto::DESKey>& desKey,
00306 IN new_player_conv_data_t& data
00307 )
00308 {
00309 ASSERT(desKey, "null");
00310 ASSERT(data.isValid(), "invalid new player data");
00311
00312 smart_ptr<NPHost> local = new NPHost;
00313 ASSERT(local, "null");
00314
00315 local->initialize(desKey, data);
00316
00317 return local;
00318 }
00319
00320
00321
00322 };
00323