Changeset 14 in chevmsgr
- Timestamp:
- 08/30/15 21:31:39 (9 years ago)
- Location:
- trunk
- Files:
-
- 10 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/cf/task.cpp
r4 r14 77 77 78 78 cf::memory::free(mMutex); 79 mMutex = NULL; 79 80 } 80 81 -
trunk/msg.cpp
r11 r14 42 42 } 43 43 44 std::string Message::serialize() const 45 { 46 return json::Serialize(mObject); 47 } 48 44 49 // request 45 50 void Request::setUserID(const std::string & id) … … 83 88 DECLARE_TEMPLATE_OBJECT(obj, ProtocolType::LOGIN); 84 89 85 obj[ProtocolType::PW] = mID + DELIMITER + pw; 90 obj[ProtocolType::PW] = pw; 91 92 return json::Serialize(obj); 93 } 94 95 std::string Request::logout() const 96 { 97 DECLARE_TEMPLATE_OBJECT(obj, ProtocolType::LOGOUT); 86 98 87 99 return json::Serialize(obj); … … 97 109 } 98 110 99 std::string Request::openSession(const std:: string & to) const111 std::string Request::openSession(const std::vector<std::string> & idList) const 100 112 { 101 113 DECLARE_TEMPLATE_OBJECT(obj, ProtocolType::OPEN_SESSION); 102 114 103 obj[ProtocolType::TO] = to; 115 json::Array ar; 116 std::vector<std::string>::const_iterator iter; 117 for (iter = idList.begin(); iter != idList.end(); iter++) 118 ar.push_back(*iter); 119 120 obj[ProtocolType::ID_LIST] = ar; 104 121 105 122 return json::Serialize(obj); 106 123 } 107 124 108 std::string Request:: chat(const std::string & sessid, const std::string & message, const int sensitive) const125 std::string Request::tell(const std::string & sessid, const std::string & message, const int sensitive) const 109 126 { 110 DECLARE_TEMPLATE_OBJECT(obj, ProtocolType:: CHAT);127 DECLARE_TEMPLATE_OBJECT(obj, ProtocolType::TELL); 111 128 112 129 obj[ProtocolType::FROM] = mID; … … 133 150 std::string Response::result(const std::string & requestType, const bool status) const 134 151 { 135 DECLARE_TEMPLATE_OBJECT(obj, ProtocolType::RESULT);152 DECLARE_TEMPLATE_OBJECT(obj, requestType); 136 153 137 154 obj[ProtocolType::RESULT] = status; -
trunk/msg.hpp
r12 r14 32 32 DECLARE_KEY(PW); 33 33 DECLARE_KEY(LOGIN); 34 DECLARE_KEY(LOGOUT); 34 35 DECLARE_KEY(ADD_FRIEND); 35 36 DECLARE_KEY(OPEN_SESSION); 36 37 DECLARE_KEY(TO); 37 DECLARE_KEY(CHAT); 38 DECLARE_KEY(LISTEN); 39 DECLARE_KEY(TELL); 38 40 DECLARE_KEY(FROM); 39 41 DECLARE_KEY(SESSION_ID); … … 50 52 class Message 51 53 { 52 p rivate:54 public: 53 55 json::Object mObject; 54 56 55 public:56 57 Message(); 57 58 … … 79 80 80 81 std::string type() const; 82 83 std::string serialize() const; 81 84 }; 82 85 … … 105 108 std::string login(const std::string & pw) const; 106 109 110 std::string logout() const; 111 107 112 std::string addFriend(const std::string & id) const; 108 113 109 std::string openSession(const std:: string & to) const;114 std::string openSession(const std::vector<std::string> & idList) const; 110 115 111 std::string chat(const std::string & sessid, const std::string & message, const int sensitive) const;116 std::string tell(const std::string & sessid, const std::string & message, const int sensitive) const; 112 117 113 118 std::string getFriendList() const; … … 122 127 123 128 std::string friendList(const std::vector<SFriend> & friendList) const; 124 125 std::string openSession(const std::vector<std::string> & idList) const;126 129 }; 127 130 }; … … 156 159 157 160 for (size_t iter = 1; iter < strings.size(); iter++) 158 concat += strings[iter];161 concat += "," + strings[iter]; 159 162 160 163 return concat; -
trunk/msgclnt.cpp
r12 r14 6 6 7 7 #include <stdlib.h> 8 9 #include "cf/codec.h" 8 10 9 11 // -------------------------------------------------------------- … … 21 23 } SCallbackWorkerArg; 22 24 23 static int messageQwor ekr(void * arg)25 static int messageQworker(void * arg) 24 26 { 25 27 SMessageQWorkerArg * inst = (SMessageQWorkerArg *)arg; 26 28 27 29 Protocol::Message message; 28 cf:: bin raw;30 cf::size_t size; 29 31 30 32 while (true) … … 32 34 try 33 35 { 34 raw = inst->socket->receive(); 36 size = 0; 37 38 cf::bin raw = inst->socket->receive(); 39 size = raw.size(); 40 35 41 message.parse(raw.toString()); 36 42 } … … 40 46 41 47 // closed 42 if (raw.size() == 0) 48 if (size == 0) 49 { 50 // dummy logout 51 message.parse(Protocol::Request().logout()); 52 inst->messageQ->push(message); 43 53 break; 54 } 44 55 } 45 56 … … 52 63 } 53 64 54 static inline SConversation toC nversation(const Protocol::Message & message)65 static inline SConversation toConversation(const Protocol::Message & message) 55 66 { 56 67 SConversation c; 68 std::string chat = message.get<std::string>(ProtocolType::MESSAGE); 69 70 if (chat.length() > 0) 71 c.message = cf::codec::hex::getInstance()->decode(chat).toString(); 57 72 58 73 c.sessid = message.get<std::string>(ProtocolType::SESSION_ID); 59 c.message = message.get<std::string>(ProtocolType::MESSAGE);60 74 c.sensitive = message.get<int>(ProtocolType::SENSITIVE); 61 c.isError = message.get<bool>(ProtocolType::RESULT);62 75 63 76 c.from = message.get<std::string>(ProtocolType::FROM); … … 84 97 while (true) 85 98 { 86 message = inst->messageQ->pop(ProtocolType:: CHAT, false);99 message = inst->messageQ->pop(ProtocolType::LISTEN, false); 87 100 if (message.type() != ProtocolType::NONE) 88 inst->callback.on Chat(toCnversation(message));101 inst->callback.onListen(toConversation(message)); 89 102 90 103 message = inst->messageQ->pop(ProtocolType::OPEN_SESSION, false); 91 104 if (message.type() != ProtocolType::NONE) 92 105 inst->callback.onOpenSession(toOpenSession(message)); 106 107 message = inst->messageQ->pop(ProtocolType::LOGOUT, false); 108 if (message.type() != ProtocolType::NONE) 109 break; 93 110 } 94 111 … … 109 126 Protocol::Message MessageQ::pop(const std::string & requestType, bool isWait) 110 127 { 111 while (isWait) 112 { 113 SYNCHRONIZED(mutex) 114 { 115 Protocol::Message message = messageQ.front(); 116 117 if (message.type() == requestType) 118 { 119 messageQ.erase(messageQ.begin()); 120 121 return message; 122 } 123 } 124 } 128 do 129 { 130 mutex.lock(); 131 if (messageQ.size() == 0) 132 { 133 mutex.unlock(); 134 continue; 135 } 136 137 Protocol::Message message = messageQ.front(); 138 139 if (message.type() == requestType) 140 { 141 messageQ.erase(messageQ.begin()); 142 mutex.unlock(); 143 return message; 144 } 145 mutex.unlock(); 146 } while (isWait); 125 147 126 148 return Protocol::Message(); // return dummy NONE … … 130 152 131 153 chev::chev() 132 : listener(messageQwor ekr),154 : listener(messageQworker), 133 155 caller(callbackWorker) 134 156 { … … 138 160 { 139 161 socket.close(); 162 listener.join(); 163 caller.join(); 140 164 } 141 165 … … 254 278 } 255 279 256 std::string chev::getSessionID(std::vector<std::string> & idList) 257 { 258 try 259 { 260 idList.insert(idList.begin(), request.getUserID()); 261 262 if (idList.size() == 2) 263 std::sort(idList.begin(), idList.end()); 264 265 std::string concat = joinStrings(idList); 280 std::string chev::getSessionID(const std::vector<std::string> & idList) 281 { 282 try 283 { 284 std::vector<std::string> toList = idList; 285 toList.insert(toList.begin(), request.getUserID()); 286 287 std::string concat = joinStrings(toList); 266 288 267 289 if (sessionMap.find(concat) == sessionMap.end()) 268 290 { 269 socket.send(request.openSession(concat)); 270 271 Protocol::Message message = messageQ.pop(ProtocolType::SESSION_ID); 272 273 if (!message.get<bool>(ProtocolType::RESULT)) 274 THROW_EXCEPTION("failed to open session id"); 291 socket.send(request.openSession(toList)); 292 293 Protocol::Message message = messageQ.pop(ProtocolType::OPEN_SESSION); 275 294 276 295 sessionMap[concat] = message.get<std::string>(ProtocolType::SESSION_ID); … … 291 310 try 292 311 { 293 const SConversation & c = conversation; 294 295 socket.send(request.chat(c.sessid, c.message, c.sensitive)); 296 297 return messageQ.pop(ProtocolType::CHAT).get<bool>(ProtocolType::RESULT); 312 SConversation c = conversation; 313 314 if (c.message.length() > 0) 315 c.message = cf::codec::hex::getInstance()->encode(c.message); 316 317 socket.send(request.tell(c.sessid, c.message, c.sensitive)); 318 319 return messageQ.pop(ProtocolType::TELL).get<bool>(ProtocolType::RESULT); 298 320 } 299 321 catch (cf::exception & e) -
trunk/msgclnt.h
r12 r14 15 15 std::string message; 16 16 int sensitive; 17 bool isError;18 17 19 18 // only for listen … … 29 28 typedef struct SCallback 30 29 { 31 int(*on Chat)(SConversation &);30 int(*onListen)(SConversation &); 32 31 int(*onOpenSession)(SOpenSession &); 33 32 } SCallback; … … 77 76 std::vector<SFriend> getFriendList(); 78 77 79 std::string getSessionID( std::vector<std::string> & idList);78 std::string getSessionID(const std::vector<std::string> & idList); 80 79 81 80 bool tell(const SConversation & conversation); -
trunk/msgsrv.cpp
r13 r14 16 16 // -------------------------------------------------------------- 17 17 18 typedef struct 18 typedef struct LoginSession 19 19 { 20 20 cf::network::tcp * sock; … … 22 22 } LoginSession; 23 23 std::map<std::string, LoginSession> gOnlineUsers; 24 25 26 // ================================================================24 std::map<std::string, std::vector<std::string> > gSessionMap; 25 26 // -------------------------------------------------------------- 27 27 28 28 int cb_getFriendList(void * userArg, int argc, char ** argv, char ** colName) … … 75 75 : db(NULL) 76 76 { 77 Init(); 77 78 } 78 79 … … 139 140 throw(cf::exception) 140 141 { 141 int result ;142 char * errMsg ;142 int result = 0; 143 char * errMsg = NULL; 143 144 144 145 result = sqlite3_exec(db, query.c_str(), cb, userArg, &errMsg); 145 146 146 147 if (result != SQLITE_OK) 147 THROW_EXCEPTION (errMsg);148 THROW_EXCEPTION("[DBERROR][" << result << "] " << errMsg); 148 149 } 149 150 … … 163 164 { 164 165 FORWARD_EXCEPTION(e); 165 166 return false;167 166 } 168 167 } … … 175 174 bool isExist = false; 176 175 std::string existQuery = "select * from T_ACCOUNT where id = '" + id + "'"; 177 std::string insertQuery = "insert into T_ACCOUNT values('" + id + "', '" + pw + "', '" + sms + "', '" + ip+ "')";176 std::string insertQuery = "insert into T_ACCOUNT(id, pw) values('" + id + "', '" + pw + "')"; 178 177 179 178 this->exec(existQuery, cb_join, &isExist); … … 282 281 { 283 282 gOnlineUsers.erase(id); 283 LOG(STR(id << " was logged out")); 284 } 285 286 static unsigned int generateSeed() 287 { 288 unsigned int ret = 0; 289 int t = (int)time(NULL); 290 291 cf::bin b; 292 b.resize(sizeof(int)); 293 294 b.set((cf::uint8_t*)&t, sizeof(int)); 295 cf::bin s = crypto().sha256(b); 296 297 memcpy(&ret, s.buffer(), sizeof(unsigned int)); 298 299 return ret; 284 300 } 285 301 … … 287 303 { 288 304 char random[8] = {0x00,}; 289 sprintf(random, "%06d", rand() % 1000000);305 sprintf(random, "%06d", generateSeed() % 1000000); 290 306 291 307 return random; … … 294 310 static std::string httpSMS(const Protocol::Message & parser) 295 311 { 296 std::string phone = parser.get<std::string>( "phone");312 std::string phone = parser.get<std::string>(ProtocolType::PHONE); 297 313 298 314 #define CRLF "\r\n" … … 306 322 CRLF; 307 323 308 Protocol::Response response;309 324 cf::network::tcp smsSock; 310 325 cf::network::host smsServer(url, 80); … … 312 327 smsSock.connect(smsServer); 313 328 smsSock.send(http); 329 smsSock.receive(); 314 330 smsSock.close(); 315 331 … … 329 345 } 330 346 331 static bool login(const Protocol::Message & parser )347 static bool login(const Protocol::Message & parser, cf::network::tcp & sock, cf::bin & key) 332 348 throw (cf::exception) 333 349 { … … 335 351 std::string pw = parser.get<std::string>(ProtocolType::PW); 336 352 337 return dbmgr.login(id, pw); 338 } 339 340 static bool chat(const Protocol::Message & parser, 341 const std::string & message) 353 bool result = dbmgr.login(id, pw); 354 if (result) 355 { 356 LoginSession loginSess; 357 loginSess.sock = &sock; 358 loginSess.key = key; 359 gOnlineUsers[id] = loginSess; 360 } 361 362 return result; 363 } 364 365 static bool chat(const Protocol::Message & message) 342 366 { 343 367 bool result = false; 344 std::string to = parser.get<std::string>(ProtocolType::TO); 345 346 if (isOnline(to)) 347 { 348 gOnlineUsers[to].sock->send(message); 368 Protocol::Message parser = message; 369 std::string sessid = parser.get<std::string>(ProtocolType::SESSION_ID); 370 std::vector<std::string> idList = gSessionMap[sessid]; 371 std::string sender = parser.get<std::string>(ProtocolType::ID); 372 parser.mObject[ProtocolType::TYPE] = ProtocolType::LISTEN; 373 std::string serialized = parser.serialize(); 374 375 for (size_t iter = 0; iter < idList.size(); iter++) 376 { 377 std::string id = idList[iter]; 378 379 if (sender != id && isOnline(id)) 380 gOnlineUsers[id].sock->send(serialized); 381 349 382 result = true; 350 383 } … … 362 395 } 363 396 364 static bool opensession(const Protocol::Message & parser) 365 { 397 static bool openSession(const Protocol::Message & message) 398 { 399 Protocol::Message parser = message; 366 400 bool result = false; 367 401 std::string sessid; 368 402 std::vector<std::string> idList = parser.getList<std::string>(ProtocolType::ID_LIST); 369 std::string concat = idList[0]; 370 371 for (size_t iter = 1; iter < concat.size(); iter++) 372 concat += idList[iter]; 403 std::string concat = joinStrings(idList); 373 404 374 405 sessid = createSessionID(concat); 375 406 407 parser.mObject[ProtocolType::SESSION_ID] = sessid; 408 std::string serialized = parser.serialize(); 409 376 410 for (size_t iter = 0; iter < idList.size(); iter++) 377 411 { 378 if (isOnline(idList[iter])) 379 gOnlineUsers[idList[iter]].sock->send(sessid); 412 std::string id = idList[iter]; 413 if (isOnline(id)) 414 gOnlineUsers[id].sock->send(serialized); 380 415 381 416 result = true; 382 417 } 383 418 419 gSessionMap[sessid] = idList; 420 384 421 return result; 385 422 } … … 396 433 static std::string workerInitiator(cf::network::tcp & sock) 397 434 { 435 Protocol::Message parser; 436 398 437 try 399 438 { 400 439 std::string sms; 440 std::string id; 441 bool loggedIn = false; 401 442 402 443 while (true) 403 444 { 404 Protocol::Message parser;405 445 parser.parse(sock.receive().toString()); 406 446 407 if (parser.type() == "sms")447 if (parser.type() == ProtocolType::SMS) 408 448 { 409 449 sms = httpSMS(parser); 410 450 } 411 else if (parser.type() == "join")451 else if (parser.type() == ProtocolType::JOIN) 412 452 { 413 if ( join(parser, sms, sock.peer().address()))453 if (!join(parser, sms, sock.peer().address())) 414 454 THROW_EXCEPTION("user(" << parser.get<std::string>(ProtocolType::ID) << ") cannot join"); 415 455 } 416 else if (parser.type() == "login")456 else if (parser.type() == ProtocolType::LOGIN) 417 457 { 418 if (login(parser)) 419 parser.get<std::string>(ProtocolType::ID); 420 } 458 std::string ip = sock.peer().address(); 459 cf::bin seed = sms + DELIMITER + ip; 460 cf::bin key = crypto().sha256(seed); 461 462 if (login(parser, sock, key)) 463 id = parser.get<std::string>(ProtocolType::ID); 464 465 loggedIn = true; 466 } 467 468 // success 469 sock.send(Protocol::Response().result(parser.type(), true)); 470 if (loggedIn) 471 return id; 421 472 } 422 473 } 423 474 catch (cf::exception & e) 424 475 { 476 sock.send(Protocol::Response().result(parser.type(), false)); 425 477 FORWARD_EXCEPTION(e); 426 478 } … … 436 488 try 437 489 { 438 workerInitiator(*sock);490 id = workerInitiator(*sock); 439 491 440 492 Protocol::Response response; … … 449 501 LOG(message); 450 502 451 if (parser.type() == "chat") 452 result = chat(parser, message); 453 else if (parser.type() == "opensession") 454 result = opensession(parser); 455 // else if (parser.type() == "getFriendList") 456 // result = 457 458 sock->send(response.result(parser.type(), result)); 503 if (parser.type() == ProtocolType::TELL) 504 { 505 result = chat(parser); 506 sock->send(response.result(parser.type(), result)); 507 } 508 else if (parser.type() == ProtocolType::OPEN_SESSION) 509 { 510 result = openSession(parser); 511 } 459 512 } 460 513 } 461 514 catch (cf::exception & e) 462 515 { 463 LOG(e. what());516 LOG(e.stackTrace()); 464 517 } 465 518 … … 472 525 { 473 526 cf::network::tcp sock; 474 475 srand((unsigned int)time(NULL));476 527 477 528 try -
trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFC.h
r4 r14 31 31 32 32 extern CChevMsgrClient_MFCApp theApp; 33 34 #include <string> 35 36 static std::string wstr2str(const std::wstring & wstr) 37 { 38 return std::string().assign(wstr.begin(), wstr.end()); 39 } 40 41 static std::wstring str2wstr(const std::string & str) 42 { 43 return std::wstring().assign(str.begin(), str.end()); 44 } -
trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFC.vcxproj
r8 r14 192 192 <ClInclude Include="ChevMsgrClient_MFC.h" /> 193 193 <ClInclude Include="ChevMsgrClient_MFCDlg.h" /> 194 <ClInclude Include="LoginDlg.h" /> 195 <ClInclude Include="RegisterDlg.h" /> 194 196 <ClInclude Include="Resource.h" /> 197 <ClInclude Include="SMSDlg.h" /> 195 198 <ClInclude Include="stdafx.h" /> 196 199 <ClInclude Include="targetver.h" /> … … 199 202 <ClCompile Include="ChevMsgrClient_MFC.cpp" /> 200 203 <ClCompile Include="ChevMsgrClient_MFCDlg.cpp" /> 204 <ClCompile Include="LoginDlg.cpp" /> 205 <ClCompile Include="RegisterDlg.cpp" /> 206 <ClCompile Include="SMSDlg.cpp" /> 201 207 <ClCompile Include="stdafx.cpp"> 202 208 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> -
trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFC.vcxproj.filters
r4 r14 34 34 <Filter>헤더 파일</Filter> 35 35 </ClInclude> 36 <ClInclude Include="LoginDlg.h"> 37 <Filter>헤더 파일</Filter> 38 </ClInclude> 39 <ClInclude Include="RegisterDlg.h"> 40 <Filter>헤더 파일</Filter> 41 </ClInclude> 42 <ClInclude Include="SMSDlg.h"> 43 <Filter>헤더 파일</Filter> 44 </ClInclude> 36 45 </ItemGroup> 37 46 <ItemGroup> … … 43 52 </ClCompile> 44 53 <ClCompile Include="stdafx.cpp"> 54 <Filter>소스 파일</Filter> 55 </ClCompile> 56 <ClCompile Include="SMSDlg.cpp"> 57 <Filter>소스 파일</Filter> 58 </ClCompile> 59 <ClCompile Include="LoginDlg.cpp"> 60 <Filter>소스 파일</Filter> 61 </ClCompile> 62 <ClCompile Include="RegisterDlg.cpp"> 45 63 <Filter>소스 파일</Filter> 46 64 </ClCompile> -
trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFCDlg.cpp
r4 r14 7 7 #include "ChevMsgrClient_MFCDlg.h" 8 8 #include "afxdialogex.h" 9 10 #include "LoginDlg.h" 11 #include "RegisterDlg.h" 12 #include "SMSDlg.h" 9 13 10 14 #ifdef _DEBUG … … 101 105 // TODO: ¿©±â¿¡ Ãß°¡ ÃʱâÈ ÀÛ¾÷À» Ãß°¡ÇÕ´Ï´Ù. 102 106 107 CLoginDlg loginDlg; 108 CSMSDlg smsDlg; 109 CRegisterDlg regDlg; 110 111 loginDlg.DoModal(); 112 103 113 return TRUE; // Æ÷Ä¿½º¸¦ ÄÁÆ®·Ñ¿¡ ¼³Á¤ÇÏÁö ¾ÊÀ¸¸é TRUE¸¦ ¹ÝȯÇÕ´Ï´Ù. 104 114 } -
trunk/msvc14/chevmsgr.sln
r13 r14 12 12 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "client\client.vcxproj", "{E1C8D6C3-6426-417E-9B20-8A8D0F824CDB}" 13 13 ProjectSection(ProjectDependencies) = postProject 14 {A5238B12-5F59-4AF2-BC5C-DD93352082FD} = {A5238B12-5F59-4AF2-BC5C-DD93352082FD} 14 15 {39F45AE4-072E-44C4-8E2B-94DAC2333A5D} = {39F45AE4-072E-44C4-8E2B-94DAC2333A5D} 15 16 EndProjectSection … … 18 19 EndProject 19 20 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ChevMsgrClient_MFC", "ChevMsgrClient_MFC\ChevMsgrClient_MFC.vcxproj", "{D1A1A73A-7E56-40FA-9D43-B8737C585D18}" 21 ProjectSection(ProjectDependencies) = postProject 22 {E1C8D6C3-6426-417E-9B20-8A8D0F824CDB} = {E1C8D6C3-6426-417E-9B20-8A8D0F824CDB} 23 EndProjectSection 20 24 EndProject 21 25 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "crypto", "crypto\crypto.vcxproj", "{A5238B12-5F59-4AF2-BC5C-DD93352082FD}" 26 EndProject 27 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testClient", "testClient\testClient.vcxproj", "{765F513C-69FF-40AA-8EAF-624AE2DCA5F0}" 28 ProjectSection(ProjectDependencies) = postProject 29 {E1C8D6C3-6426-417E-9B20-8A8D0F824CDB} = {E1C8D6C3-6426-417E-9B20-8A8D0F824CDB} 30 EndProjectSection 22 31 EndProject 23 32 Global … … 69 78 {A5238B12-5F59-4AF2-BC5C-DD93352082FD}.Release|x86.ActiveCfg = Release|Win32 70 79 {A5238B12-5F59-4AF2-BC5C-DD93352082FD}.Release|x86.Build.0 = Release|Win32 80 {765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Debug|x64.ActiveCfg = Debug|x64 81 {765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Debug|x64.Build.0 = Debug|x64 82 {765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Debug|x86.ActiveCfg = Debug|Win32 83 {765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Debug|x86.Build.0 = Debug|Win32 84 {765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Release|x64.ActiveCfg = Release|x64 85 {765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Release|x64.Build.0 = Release|x64 86 {765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Release|x86.ActiveCfg = Release|Win32 87 {765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Release|x86.Build.0 = Release|Win32 71 88 EndGlobalSection 72 89 GlobalSection(SolutionProperties) = preSolution
Note:
See TracChangeset
for help on using the changeset viewer.