00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "evautil.h"
00021 #include <string>
00022 #ifdef _WIN32
00023 #include <winsock.h>
00024 #else
00025 #include <arpa/inet.h>
00026 #endif
00027 #include "md5.h"
00028
00029 const char EvaUtil::smileyMap[QQ_SMILEY_AMOUNT] = {
00030 0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,
00031 0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x73,
00032 0x74,0x75,0x76,0x77,0x8a,0x8b,0x8c,0x8d,
00033 0x8e,0x8f,0x78,0x79,0x7a,0x7b,0x90,0x91,
00034 0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,
00035 0x59,0x5a,0x5c,0x58,0x57,0x55,0x7c,0x7d,
00036 0x7e,0x7f,0x9a,0x9b,0x60,0x67,0x9c,0x9d,
00037 0x9e,0x5e,0x9f,0x89,0x80,0x81,0x82,0x62,
00038 0x63,0x64,0x65,0x66,0x83,0x68,0x84,0x85,
00039 0x86,0x87,0x6b,0x6e,0x6f,0x70,0x88,0xa0,
00040 0x50,0x51,0x52,0x53,0x54,0x56,0x5b,0x5d,
00041 0x5f,0x61,0x69,0x6a,0x6c,0x6d,0x71,0x72,
00042 };
00043
00044 char EvaUtil::md5Buf[KEY_LENGTH];
00045
00046 EvaUtil::textMap EvaUtil::map[QQ_SMILEY_AMOUNT];
00047
00048 EvaUtil::EvaUtil()
00049 {
00050 initMap();
00051 }
00052
00053 char *EvaUtil::doMd5(char *in, int len)
00054 {
00055 md5_state_t ctx;
00056 md5_init(&ctx);
00057 md5_append(&ctx, (md5_byte_t *)in, len);
00058 md5_finish(&ctx, (md5_byte_t *)md5Buf);
00059 return md5Buf;
00060 }
00061
00062 char *EvaUtil::doMd5Md5(char *in, int len)
00063 {
00064 doMd5(in, len);
00065 doMd5(md5Buf, KEY_LENGTH);
00066 return md5Buf;
00067 }
00068
00069 std::string EvaUtil::smileyToText(const char smileyCode)
00070 {
00071 int i = smileyToFileIndex(smileyCode);
00072 std::string text = map[i].py;
00073 return text;
00074 }
00075
00076 char EvaUtil::textToSmiley(const std::string &textTag)
00077 {
00078 std::string strEn, strPy;
00079 for(int i=0; i<QQ_SMILEY_AMOUNT; i++){
00080 strEn = map[i].en;
00081 strPy = map[i].py;
00082 if(strEn == textTag || strPy == textTag){
00083 return smileyMap[i];
00084 }
00085 }
00086 return 0;
00087 }
00088
00089 int EvaUtil::textToFileIndex(const std::string &textTag)
00090 {
00091 char s = textToSmiley(textTag);
00092 return smileyToFileIndex(s);
00093 }
00094
00095 int EvaUtil::smileyToFileIndex( const char smileyCode)
00096 {
00097 for(int i=0; i<QQ_SMILEY_AMOUNT; i++){
00098 if(smileyMap[i]==smileyCode)
00099 return i;
00100 }
00101 return -1;
00102 }
00103
00104 std::string EvaUtil::fileIndexToText( const int fileIndex)
00105 {
00106 if(fileIndex<0 || fileIndex > 95 ) return "";
00107 return map[fileIndex].py;
00108 }
00109
00110 std::string EvaUtil::convertToSend( const std::string & text)
00111 {
00112 std::string converted = "";
00113 int offset=0;
00114 char smileyTag = 0x14;
00115 char customTag = 0x15;
00116 bool isFirst32 = true;
00117 std::string code32FileTag = "";
00118 char seperator32_1 = 0x13;
00119 char seperator32_2 = 0x4c;
00120 for(uint i=0; i< text.length(); i++){
00121 if(text[i] == '/'){
00122 offset = i;
00123 while(text[offset] != 0x00 && text[++offset]!=' ');
00124 if((offset - i)<8){
00125 char code = textToSmiley(text.substr(i,offset-i));
00126 if(code){
00127 converted += smileyTag;
00128 converted += code;
00129 i=offset;
00130 continue;
00131 }
00132 }
00133 converted+=text[i];
00134 continue;
00135 }else{
00136 if(text[i] == '['){
00137 std::string zdyTag = text.substr(i, 5);
00138 if(zdyTag == "[ZDY]"){
00139 offset = text.find("[/ZDY]", i);
00140 std::string zdyType = text.substr(i+6, 2);
00141 zdyTag = text.substr(i+5+4, offset-i-14);
00142 std::string sendFormat;
00143 sendFormat += customTag;
00144 if(zdyType == "32"){
00145 if(isFirst32){
00146 code32FileTag = zdyTag.substr(0, zdyTag.length() - 7);
00147 code32FileTag += seperator32_1;
00148 code32FileTag += seperator32_2;
00149 isFirst32 = false;
00150 }
00151 sendFormat += "2";
00152 sendFormat += zdyTag.substr(zdyTag.length() - 2, 2);
00153 sendFormat += "999999";
00154 } else if(zdyType == "36"){
00155 sendFormat += "6";
00156 int len = zdyTag.length() + 5;
00157 char *strLen = new char[4];
00158 sprintf(strLen, "%3d", len);
00159 sendFormat += strLen;
00160 delete strLen;
00161 sendFormat += zdyTag;
00162 }
00163 converted += sendFormat;
00164 i += (offset - i + 5);
00165 continue;
00166 }
00167 }
00168 }
00169 converted+=text[i];
00170 }
00171 if(!isFirst32)
00172 converted = code32FileTag + converted;
00173 return converted;
00174 }
00175
00176 std::string EvaUtil::convertToSend(const std::string &text, bool *hasImage)
00177 {
00178 std::string converted = "";
00179 int offset=0;
00180 char smileyTag = 0x14;
00181 char customTag = 0x15;
00182 bool isFirst32 = true;
00183 std::string code32FileTag = "";
00184 char seperator32_1 = 0x13;
00185 char seperator32_2 = 0x4c;
00186 for(uint i=0; i< text.length(); i++){
00187 if(text[i] == '/'){
00188 offset = i;
00189 while(text[offset] != 0x00 && text[++offset]!=' ');
00190 if((offset - i)<8){
00191 char code = textToSmiley(text.substr(i,offset-i));
00192 if(code){
00193 converted += smileyTag;
00194 converted += code;
00195 i=offset;
00196 continue;
00197 }
00198 }
00199 converted+=text[i];
00200 continue;
00201 }else{
00202 if(text[i] == '['){
00203 std::string zdyTag = text.substr(i, 5);
00204 if(zdyTag == "[ZDY]"){
00205 offset = text.find("[/ZDY]", i);
00206 std::string zdyType = text.substr(i+6, 2);
00207 zdyTag = text.substr(i+5+4, offset-i-14);
00208 std::string sendFormat;
00209 sendFormat += customTag;
00210 if(zdyType == "32"){
00211 if(isFirst32){
00212 code32FileTag = zdyTag.substr(0, zdyTag.length() - 7);
00213 code32FileTag += seperator32_1;
00214 code32FileTag += seperator32_2;
00215 isFirst32 = false;
00216 }
00217 sendFormat += "2";
00218 sendFormat += zdyTag.substr(zdyTag.length() - 2, 2);
00219 sendFormat += "999999";
00220 } else if(zdyType == "36"){
00221 sendFormat += "6";
00222 int len = zdyTag.length() + 5;
00223 char *strLen = new char[4];
00224 sprintf(strLen, "%3d", len);
00225 sendFormat += strLen;
00226 delete strLen;
00227 sendFormat += zdyTag;
00228 }
00229 converted += sendFormat;
00230 i += (offset - i + 5);
00231 continue;
00232 }
00233 }
00234 }
00235 converted+=text[i];
00236 }
00237 if(!isFirst32){
00238 converted = code32FileTag + converted;
00239 *hasImage = true;
00240 } else
00241 *hasImage = false;
00242 return converted;
00243 }
00244
00245 void EvaUtil::initMap()
00246 {
00247 strcpy(map[0].en,"/:o"); strcpy(map[0].py, "/jy");
00248 strcpy(map[1].en, "/:~"); strcpy(map[1].py, "/pz");
00249 strcpy(map[2].en, "/:*"); strcpy(map[2].py, "/se");
00250 strcpy(map[3].en, "/:|"); strcpy(map[3].py, "/fd");
00251 strcpy(map[4].en, "/8-)"); strcpy(map[4].py, "/dy");
00252 strcpy(map[5].en, "/:<"); strcpy(map[5].py, "/ll");
00253 strcpy(map[6].en, "/:$"); strcpy(map[6].py, "/hx");
00254 strcpy(map[7].en, "/:x"); strcpy(map[7].py, "/bz");
00255 strcpy(map[8].en, "/:z"); strcpy(map[8].py, "/shui");
00256 strcpy(map[9].en, "/:'"); strcpy(map[9].py, "/dk");
00257
00258 strcpy(map[10].en, "/:-|"); strcpy(map[10].py, "/gg");
00259 strcpy(map[11].en, "/:@"); strcpy(map[11].py, "/fn");
00260 strcpy(map[12].en, "/:P"); strcpy(map[12].py, "/tp");
00261 strcpy(map[13].en, "/:D"); strcpy(map[13].py, "/cy");
00262 strcpy(map[14].en, "/:)"); strcpy(map[14].py, "/wx");
00263 strcpy(map[15].en, "/:("); strcpy(map[15].py, "/ng");
00264 strcpy(map[16].en, "/:+"); strcpy(map[16].py, "/kuk");
00265 strcpy(map[17].en, "/:#"); strcpy(map[17].py, "/feid");
00266 strcpy(map[18].en, "/:Q"); strcpy(map[18].py, "/zk");
00267 strcpy(map[19].en, "/:t"); strcpy(map[19].py, "/tu");
00268
00269
00270 strcpy(map[20].en, "/;P"); strcpy(map[20].py, "/tx");
00271 strcpy(map[21].en, "/;-D"); strcpy(map[21].py, "/ka");
00272 strcpy(map[22].en, "/;d"); strcpy(map[22].py, "/baiy");
00273 strcpy(map[23].en, "/;o"); strcpy(map[23].py, "/am");
00274 strcpy(map[24].en, "/:g"); strcpy(map[24].py, "/jie");
00275 strcpy(map[25].en, "/|-)"); strcpy(map[25].py, "/kun");
00276 strcpy(map[26].en, "/:!"); strcpy(map[26].py, "/jk");
00277 strcpy(map[27].en, "/:L"); strcpy(map[27].py, "/lh");
00278 strcpy(map[28].en, "/:>"); strcpy(map[28].py, "/hanx");
00279 strcpy(map[29].en, "/:;"); strcpy(map[29].py, "/db");
00280
00281 strcpy(map[30].en, "/;f"); strcpy(map[30].py, "/fendou");
00282 strcpy(map[31].en, "/:-S"); strcpy(map[31].py, "/zhm");
00283 strcpy(map[32].en, "/?"); strcpy(map[32].py, "/yiw");
00284 strcpy(map[33].en, "/;x"); strcpy(map[33].py, "/xu");
00285 strcpy(map[34].en, "/;@"); strcpy(map[34].py, "/yun");
00286 strcpy(map[35].en, "/:8"); strcpy(map[35].py, "/zhem");
00287 strcpy(map[36].en, "/;!"); strcpy(map[36].py, "/shuai");
00288 strcpy(map[37].en, "/!!!"); strcpy(map[37].py, "/kl");
00289 strcpy(map[38].en, "/xx"); strcpy(map[38].py, "/qiao");
00290 strcpy(map[39].en, "/bye"); strcpy(map[39].py, "/zj");
00291
00292
00293 strcpy(map[40].en, "/go"); strcpy(map[40].py, "/shan");
00294 strcpy(map[41].en, "/shake"); strcpy(map[41].py, "/fad");
00295 strcpy(map[42].en, "/love"); strcpy(map[42].py, "/aiq");
00296 strcpy(map[43].en, "/jump"); strcpy(map[43].py, "/tiao");
00297 strcpy(map[44].en, "/find"); strcpy(map[44].py, "/zhao");
00298 strcpy(map[45].en, "/&"); strcpy(map[45].py, "/mm");
00299 strcpy(map[46].en, "/pig"); strcpy(map[46].py, "/zt");
00300 strcpy(map[47].en, "/cat"); strcpy(map[47].py, "/maom");
00301 strcpy(map[48].en, "/dog"); strcpy(map[48].py, "/xg");
00302 strcpy(map[49].en, "/hug"); strcpy(map[49].py, "/yb");
00303
00304 strcpy(map[50].en, "/$"); strcpy(map[50].py, "/qianc");
00305 strcpy(map[51].en, "/(!)"); strcpy(map[51].py, "/dp");
00306 strcpy(map[52].en, "/cup"); strcpy(map[52].py, "/bei");
00307 strcpy(map[53].en, "/cake"); strcpy(map[53].py, "/dg");
00308 strcpy(map[54].en, "/li"); strcpy(map[54].py, "/shd");
00309 strcpy(map[55].en, "/bome"); strcpy(map[55].py, "/zhd");
00310 strcpy(map[56].en, "/kn"); strcpy(map[56].py, "/dao");
00311 strcpy(map[57].en, "/footb"); strcpy(map[57].py, "/zq");
00312 strcpy(map[58].en, "/music"); strcpy(map[58].py, "/yy");
00313 strcpy(map[59].en, "/shit"); strcpy(map[59].py, "/bb");
00314
00315
00316 strcpy(map[60].en, "/coffee"); strcpy(map[60].py, "/kf");
00317 strcpy(map[61].en, "/eat"); strcpy(map[61].py, "/fa");
00318 strcpy(map[62].en, "/pill"); strcpy(map[62].py, "/yw");
00319 strcpy(map[63].en, "/rose"); strcpy(map[63].py, "/mg");
00320 strcpy(map[64].en, "/fade"); strcpy(map[64].py, "/dx");
00321 strcpy(map[65].en, "/kiss"); strcpy(map[65].py, "/wen");
00322 strcpy(map[66].en, "/heart"); strcpy(map[66].py, "/xin");
00323 strcpy(map[67].en, "/break"); strcpy(map[67].py, "/xs");
00324 strcpy(map[68].en, "/meeting"); strcpy(map[68].py, "/hy");
00325 strcpy(map[69].en, "/gift"); strcpy(map[69].py, "/lw");
00326
00327 strcpy(map[70].en, "/phone"); strcpy(map[70].py, "/dh");
00328 strcpy(map[71].en, "/time"); strcpy(map[71].py, "/sj");
00329 strcpy(map[72].en, "/email"); strcpy(map[72].py, "/yj");
00330 strcpy(map[73].en, "/tv"); strcpy(map[73].py, "/ds");
00331 strcpy(map[74].en, "/sun"); strcpy(map[74].py, "/ty");
00332 strcpy(map[75].en, "/moon"); strcpy(map[75].py, "/yl");
00333 strcpy(map[76].en, "/strong"); strcpy(map[76].py, "/qiang");
00334 strcpy(map[77].en, "/weak"); strcpy(map[77].py, "/ruo");
00335 strcpy(map[78].en, "/share"); strcpy(map[78].py, "/ws");
00336 strcpy(map[79].en, "/v"); strcpy(map[79].py, "/shl");
00337
00338
00339 strcpy(map[80].en, "/<D>"); strcpy(map[80].py, "/dd");
00340 strcpy(map[81].en, "/<J>"); strcpy(map[81].py, "/mn");
00341 strcpy(map[82].en, "/<H>"); strcpy(map[82].py, "/hl");
00342 strcpy(map[83].en, "/<M>"); strcpy(map[83].py, "/mamao");
00343 strcpy(map[84].en, "/<QQ>"); strcpy(map[84].py, "/qz");
00344 strcpy(map[85].en, "/<L>"); strcpy(map[85].py, "/fw");
00345 strcpy(map[86].en, "/<O>"); strcpy(map[86].py, "/oh");
00346 strcpy(map[87].en, "/<B>"); strcpy(map[87].py, "/bj");
00347 strcpy(map[88].en, "/<U>"); strcpy(map[88].py, "/qsh");
00348 strcpy(map[89].en, "/<W>"); strcpy(map[89].py, "/xig");
00349
00350 strcpy(map[90].en, "/<!!>"); strcpy(map[90].py, "/xy");
00351 strcpy(map[91].en, "/<~>"); strcpy(map[91].py, "/duoy");
00352 strcpy(map[92].en, "/<Z>"); strcpy(map[92].py, "/xr");
00353 strcpy(map[93].en, "/<*>"); strcpy(map[93].py, "/xixing");
00354 strcpy(map[94].en, "/<00>"); strcpy(map[94].py, "/nv");
00355 strcpy(map[95].en, "/<11>"); strcpy(map[95].py, "/nan");
00356 };
00357
00358 void EvaUtil::calcSuns( const unsigned short level, int * suns, int * moons, int * stars )
00359 {
00360 *suns = 0;
00361 *moons = 0;
00362 *stars = 0;
00363
00364 *suns = level/16;
00365 *moons = (level%16)/4;
00366 *stars = level%4;
00367 }
00368
00369 std::string EvaUtil::customSmileyToText( const char * buf, int * smileyLength, const char *uuid)
00370 {
00371 if(buf[0] != 0x15) return "";
00372
00373 char *strTmp = new char[1000];
00374 std::string strRet = "[ZDY]";
00375 int pos=1;
00376 switch( buf[pos++] ){
00377 case 0x32:{
00378 if(!uuid) break;
00379 char ext = buf[pos++];
00380 char seq = buf[pos++] - 0x11;
00381 pos += 6;
00382
00383 strRet += "[32]";
00384 strRet += uuid;
00385 strRet += seq;
00386 switch(ext){
00387 case 'A':
00388 strRet += ".jpg";
00389 break;
00390 case 'C':
00391 strRet += ".gif";
00392 default:
00393 printf("EvaUtil::customSmileyToText -- unknown file extension : 0x%2x\n", 0xff&ext);
00394 break;
00395 }
00396 strRet += "[/32]";
00397 }
00398 break;
00399 case 0x33:{
00400 pos++;
00401 memcpy(strTmp, buf+pos, 32 + 1 + 3);
00402 strTmp[32 + 1 + 3] = 0x00;
00403 pos += (32+1+3);
00404
00405 strRet += "[33]";
00406 strRet += std::string(strTmp);
00407
00408 int len = (buf[pos++] - 'A') & 0xff;
00409 memcpy(strTmp, buf+pos, len);
00410 strTmp[len] = 0x00;
00411 pos += len;
00412
00413 strRet += std::string(strTmp);
00414 strRet += "[/33]";
00415 }
00416 break;
00417 case 0x34:{
00418 strRet += "[34]";
00419 strRet += buf[pos++];
00420 strRet += "[/34]";
00421 }
00422 break;
00423 case 0x36:{
00424 char *partLen = new char[4];
00425 int lenLen = 0;
00426 while(buf[pos + lenLen] == 0x20){
00427 partLen[lenLen++] = '0';
00428 };
00429 memcpy(partLen + lenLen, buf + pos + lenLen, 3 - lenLen);
00430 partLen[3]=0x00;
00431 int len = atoi(partLen);printf("36 len:%d\n",len);
00432 delete partLen;
00433
00434 strRet += "[36]";
00435 memcpy(strTmp, buf+pos+3, len - pos - 3);
00436 strTmp[len - pos - 3] = 0x00;
00437 strRet += strTmp;
00438 strRet += "[/36]";
00439
00440 pos = len;
00441 }
00442 break;
00443 case 0x37:{
00444 char *partLen = new char[4];
00445 int lenLen = 0;
00446 while(buf[pos + lenLen] == 0x20){
00447 partLen[lenLen++] = '0';
00448 };
00449 memcpy(partLen + lenLen, buf + pos + lenLen, 3 - lenLen);
00450 partLen[3]=0x00;
00451 int len = atoi(partLen);printf("37 len:%d\n",len);
00452 delete partLen;
00453
00454 strRet += "[37]";
00455 memcpy(strTmp, buf+pos+3, len -pos-3);
00456 strTmp[len - pos - 3] = 0x00;
00457 strRet += strTmp;
00458 strRet += "[/37]";
00459
00460 pos = len;
00461 }
00462 break;
00463 default:
00464 sprintf(strTmp,"%d", buf[pos-1]);
00465 strRet += "[";
00466 strRet += strTmp;
00467 strRet += "]";
00468 break;
00469 }
00470 delete strTmp;
00471 *smileyLength = pos;
00472 strRet += "[/ZDY]";
00473
00474 return strRet;
00475 }
00476
00477 int EvaUtil::write16(unsigned char *buf, const unsigned short value )
00478 {
00479 unsigned short tmp = htons(value);
00480 memcpy(buf, &tmp, 2);
00481 return 2;
00482 }
00483
00484 int EvaUtil::write32( unsigned char *buf, const unsigned int value )
00485 {
00486 unsigned int tmp = htonl(value);
00487 memcpy(buf, &tmp, 4);
00488 return 4;
00489 }
00490
00491 unsigned short EvaUtil::read16( const unsigned char * buf )
00492 {
00493 unsigned short tmp;
00494 memcpy(&tmp, buf, 2);
00495 return ntohs(tmp);
00496 }
00497
00498 unsigned int EvaUtil::read32( const unsigned char * buf )
00499 {
00500 unsigned int tmp;
00501 memcpy(&tmp, buf, 4);
00502 return ntohl(tmp);
00503 }