├── .gitignore ├── Changs ├── LICENSE ├── README.md ├── build.sh ├── core ├── build.sh ├── conf │ ├── env │ └── special_list.txt ├── robot-tuling │ ├── README-Tuling │ ├── README-cJSON │ ├── cJSON.c │ ├── cJSON.h │ └── tuling-cli.c ├── robot.sh ├── robot │ ├── allow.lst │ ├── ans.txt │ ├── ans_abs.txt │ ├── err.lst │ ├── findans.c │ ├── getdata.c │ ├── normal.sh │ ├── ques.txt │ ├── ques_abs.txt │ ├── same.c │ ├── same_abs.c │ └── study.sh └── start.sh ├── doc └── robot.txt ├── screenshot └── screenshot.png ├── start.pl ├── tools ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── screenshots │ ├── screenshot1.png │ ├── screenshot2.png │ ├── webqq_qr.png │ └── weixin_qr.jpg └── viewqr.c └── version /.gitignore: -------------------------------------------------------------------------------- 1 | /core/qqlog.txt 2 | /core/robot/same 3 | /core/robot/same_abs 4 | /core/robot/getdata 5 | /core/robot/findans 6 | /account.txt 7 | /core/robot-tuling/settings.cfg 8 | /core/robot-tuling/test 9 | /core/robot-tuling/settings.cfg 10 | /tools/viewqr 11 | -------------------------------------------------------------------------------- /Changs: -------------------------------------------------------------------------------- 1 | # Version 2.5.1 2 | 1.修复不回复消息的Bug 3 | 4 | # version 2.5.0 5 | 1.去除QQ号输入,自动识别QQ号 6 | 2.Mojo-Webqq版本最低要求1.7.9 7 | 8 | # version 2.4.5 9 | 1.更改部分函数名 10 | 11 | # version 2.4.4 12 | 1.修复版本判断的bug 13 | 14 | # version 2.4.3 15 | 1.修复build.sh重复询问API的bug 16 | 2.二维码输出有问题,故修改$client->print()为print 17 | 18 | # version 2.4.2 19 | 1.修改ViewQR工具回调方式 20 | 2.Mojo-Webqq版本最低要求1.7.7 21 | 22 | # version 2.4.1 23 | 1.修改以子项目的方式管理viewqr工具,方便管理 24 | 25 | # version 2.4.0 26 | 1.添加终端显示二维码功能,省去打开图片的功夫 27 | 2.添加Changs文件 28 | 3.修改README.md为markdown格式 29 | 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | 167 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 截图预览 2 | ![image](https://github.com/ljkgpxs/QRobot/raw/master/screenshot/screenshot.png) 3 | 4 | ### 安装 5 | 安装依赖
6 | ## Ubuntu: 7 | ``` 8 | $ sudo apt-get install libpng12-dev libcurl4-openssl-dev libjpeg-dev 9 | ``` 10 | 11 | ## Centos: 12 | ``` 13 | # yum install libpng12-devel libcurl-devel libjpeg-devel 14 | ``` 15 | 安装Mojo-Webqq依赖,项目地址: [Mojo-Webqq](https://github.com/sjdy521/Mojo-Webqq) 16 |
17 | 18 | 编译:
19 | 需要gcc编译器 20 | ``` 21 | $ ./build.sh 22 | ``` 23 | 24 | `perl版本最低要求 5.10` 25 | ### 使用 26 | ``` 27 | $ ./start.pl 28 | ``` 29 | 根据提示进行账号键入和二维码扫描 30 | 31 | 32 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # QRobot Project By Ljkgpxs 3 | 4 | if [ -f `which gcc` ]; then 5 | : 6 | else 7 | echo "Gcc not found, please install Gcc,or compile core/robot/*.c by yourself." 8 | exit 1; 9 | fi 10 | 11 | cd core/ 12 | echo "**Building Robot" 13 | ./build.sh 14 | cd ../tools/ 15 | # echo "**Building tools.viewqr" 16 | # gcc viewqr.c -o viewqr -lpng -O3 -Wall 17 | make 18 | echo "**Done" 19 | 20 | cd .. 21 | if [ -s ./core/robot-tuling/settings.cfg ]; then 22 | exit 0; 23 | fi 24 | 25 | echo "please input tuling robot api key, if you dont have it, input ENTER directly(http://www.tuling123.com)" 26 | read key 27 | if [ $key ]; then 28 | echo "Writting key to \"core/robot-tuling/settings.cfg\"" 29 | echo $key >core/robot-tuling/settings.cfg 30 | else 31 | echo "No key input...skip" 32 | print >core/robot-tuling/settings.cfg 33 | fi 34 | 35 | 36 | -------------------------------------------------------------------------------- /core/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . ./conf/env 3 | cd $robot_dir 4 | 5 | echo " CC findans" 6 | gcc findans.c -o findans 7 | chmod 775 findans 8 | 9 | echo " CC same" 10 | gcc same.c -o same 11 | chmod 775 same 12 | 13 | echo " CC getdata" 14 | gcc getdata.c -o getdata 15 | chmod 775 getdata 16 | 17 | echo " CC same_abs" 18 | gcc same_abs.c -o same_abs 19 | chmod 775 same_abs 20 | 21 | cd ../robot-tuling 22 | 23 | echo " CC tuling-cli(optional)" 24 | gcc tuling-cli.c cJSON.c -o test -lcurl -lm 25 | if [ $? != 0 ]; then 26 | echo "Please install libcurl" 27 | fi 28 | 29 | -------------------------------------------------------------------------------- /core/conf/env: -------------------------------------------------------------------------------- 1 | export robot_dir=./robot 2 | -------------------------------------------------------------------------------- /core/conf/special_list.txt: -------------------------------------------------------------------------------- 1 | # input your special care QQ number here 2 | -------------------------------------------------------------------------------- /core/robot-tuling/README-Tuling: -------------------------------------------------------------------------------- 1 | Project home page : 2 | http://www.tuling123.com 3 | -------------------------------------------------------------------------------- /core/robot-tuling/README-cJSON: -------------------------------------------------------------------------------- 1 | Project home page : 2 | http://sourceforge.net/projects/cjson/ 3 | -------------------------------------------------------------------------------- /core/robot-tuling/cJSON.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Dave Gamble 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | /* cJSON */ 24 | /* JSON parser in C. */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "cJSON.h" 34 | 35 | static const char *ep; 36 | 37 | const char *cJSON_GetErrorPtr(void) {return ep;} 38 | 39 | static int cJSON_strcasecmp(const char *s1,const char *s2) 40 | { 41 | if (!s1) return (s1==s2)?0:1;if (!s2) return 1; 42 | for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0; 43 | return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2); 44 | } 45 | 46 | static void *(*cJSON_malloc)(size_t sz) = malloc; 47 | static void (*cJSON_free)(void *ptr) = free; 48 | 49 | static char* cJSON_strdup(const char* str) 50 | { 51 | size_t len; 52 | char* copy; 53 | 54 | len = strlen(str) + 1; 55 | if (!(copy = (char*)cJSON_malloc(len))) return 0; 56 | memcpy(copy,str,len); 57 | return copy; 58 | } 59 | 60 | void cJSON_InitHooks(cJSON_Hooks* hooks) 61 | { 62 | if (!hooks) { /* Reset hooks */ 63 | cJSON_malloc = malloc; 64 | cJSON_free = free; 65 | return; 66 | } 67 | 68 | cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; 69 | cJSON_free = (hooks->free_fn)?hooks->free_fn:free; 70 | } 71 | 72 | /* Internal constructor. */ 73 | static cJSON *cJSON_New_Item(void) 74 | { 75 | cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); 76 | if (node) memset(node,0,sizeof(cJSON)); 77 | return node; 78 | } 79 | 80 | /* Delete a cJSON structure. */ 81 | void cJSON_Delete(cJSON *c) 82 | { 83 | cJSON *next; 84 | while (c) 85 | { 86 | next=c->next; 87 | if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child); 88 | if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); 89 | if (!(c->type&cJSON_StringIsConst) && c->string) cJSON_free(c->string); 90 | cJSON_free(c); 91 | c=next; 92 | } 93 | } 94 | 95 | /* Parse the input text to generate a number, and populate the result into item. */ 96 | static const char *parse_number(cJSON *item,const char *num) 97 | { 98 | double n=0,sign=1,scale=0;int subscale=0,signsubscale=1; 99 | 100 | if (*num=='-') sign=-1,num++; /* Has sign? */ 101 | if (*num=='0') num++; /* is zero */ 102 | if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */ 103 | if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */ 104 | if (*num=='e' || *num=='E') /* Exponent? */ 105 | { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */ 106 | while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */ 107 | } 108 | 109 | n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */ 110 | 111 | item->valuedouble=n; 112 | item->valueint=(int)n; 113 | item->type=cJSON_Number; 114 | return num; 115 | } 116 | 117 | static int pow2gt (int x) { --x; x|=x>>1; x|=x>>2; x|=x>>4; x|=x>>8; x|=x>>16; return x+1; } 118 | 119 | typedef struct {char *buffer; int length; int offset; } printbuffer; 120 | 121 | static char* ensure(printbuffer *p,int needed) 122 | { 123 | char *newbuffer;int newsize; 124 | if (!p || !p->buffer) return 0; 125 | needed+=p->offset; 126 | if (needed<=p->length) return p->buffer+p->offset; 127 | 128 | newsize=pow2gt(needed); 129 | newbuffer=(char*)cJSON_malloc(newsize); 130 | if (!newbuffer) {cJSON_free(p->buffer);p->length=0,p->buffer=0;return 0;} 131 | if (newbuffer) memcpy(newbuffer,p->buffer,p->length); 132 | cJSON_free(p->buffer); 133 | p->length=newsize; 134 | p->buffer=newbuffer; 135 | return newbuffer+p->offset; 136 | } 137 | 138 | static int update(printbuffer *p) 139 | { 140 | char *str; 141 | if (!p || !p->buffer) return 0; 142 | str=p->buffer+p->offset; 143 | return p->offset+strlen(str); 144 | } 145 | 146 | /* Render the number nicely from the given item into a string. */ 147 | static char *print_number(cJSON *item,printbuffer *p) 148 | { 149 | char *str=0; 150 | double d=item->valuedouble; 151 | if (d==0) 152 | { 153 | if (p) str=ensure(p,2); 154 | else str=(char*)cJSON_malloc(2); /* special case for 0. */ 155 | if (str) strcpy(str,"0"); 156 | } 157 | else if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) 158 | { 159 | if (p) str=ensure(p,21); 160 | else str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */ 161 | if (str) sprintf(str,"%d",item->valueint); 162 | } 163 | else 164 | { 165 | if (p) str=ensure(p,64); 166 | else str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */ 167 | if (str) 168 | { 169 | if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d); 170 | else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d); 171 | else sprintf(str,"%f",d); 172 | } 173 | } 174 | return str; 175 | } 176 | 177 | static unsigned parse_hex4(const char *str) 178 | { 179 | unsigned h=0; 180 | if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; 181 | h=h<<4;str++; 182 | if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; 183 | h=h<<4;str++; 184 | if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; 185 | h=h<<4;str++; 186 | if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; 187 | return h; 188 | } 189 | 190 | /* Parse the input text into an unescaped cstring, and populate item. */ 191 | static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; 192 | static const char *parse_string(cJSON *item,const char *str) 193 | { 194 | const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2; 195 | if (*str!='\"') {ep=str;return 0;} /* not a string! */ 196 | 197 | while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */ 198 | 199 | out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */ 200 | if (!out) return 0; 201 | 202 | ptr=str+1;ptr2=out; 203 | while (*ptr!='\"' && *ptr) 204 | { 205 | if (*ptr!='\\') *ptr2++=*ptr++; 206 | else 207 | { 208 | ptr++; 209 | switch (*ptr) 210 | { 211 | case 'b': *ptr2++='\b'; break; 212 | case 'f': *ptr2++='\f'; break; 213 | case 'n': *ptr2++='\n'; break; 214 | case 'r': *ptr2++='\r'; break; 215 | case 't': *ptr2++='\t'; break; 216 | case 'u': /* transcode utf16 to utf8. */ 217 | uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */ 218 | 219 | if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */ 220 | 221 | if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */ 222 | { 223 | if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */ 224 | uc2=parse_hex4(ptr+3);ptr+=6; 225 | if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */ 226 | uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF)); 227 | } 228 | 229 | len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len; 230 | 231 | switch (len) { 232 | case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; 233 | case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; 234 | case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; 235 | case 1: *--ptr2 =(uc | firstByteMark[len]); 236 | } 237 | ptr2+=len; 238 | break; 239 | default: *ptr2++=*ptr; break; 240 | } 241 | ptr++; 242 | } 243 | } 244 | *ptr2=0; 245 | if (*ptr=='\"') ptr++; 246 | item->valuestring=out; 247 | item->type=cJSON_String; 248 | return ptr; 249 | } 250 | 251 | /* Render the cstring provided to an escaped version that can be printed. */ 252 | static char *print_string_ptr(const char *str,printbuffer *p) 253 | { 254 | const char *ptr;char *ptr2,*out;int len=0,flag=0;unsigned char token; 255 | 256 | for (ptr=str;*ptr;ptr++) flag|=((*ptr>0 && *ptr<32)||(*ptr=='\"')||(*ptr=='\\'))?1:0; 257 | if (!flag) 258 | { 259 | len=ptr-str; 260 | if (p) out=ensure(p,len+3); 261 | else out=(char*)cJSON_malloc(len+3); 262 | if (!out) return 0; 263 | ptr2=out;*ptr2++='\"'; 264 | strcpy(ptr2,str); 265 | ptr2[len]='\"'; 266 | ptr2[len+1]=0; 267 | return out; 268 | } 269 | 270 | if (!str) 271 | { 272 | if (p) out=ensure(p,3); 273 | else out=(char*)cJSON_malloc(3); 274 | if (!out) return 0; 275 | strcpy(out,"\"\""); 276 | return out; 277 | } 278 | ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;} 279 | 280 | if (p) out=ensure(p,len+3); 281 | else out=(char*)cJSON_malloc(len+3); 282 | if (!out) return 0; 283 | 284 | ptr2=out;ptr=str; 285 | *ptr2++='\"'; 286 | while (*ptr) 287 | { 288 | if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; 289 | else 290 | { 291 | *ptr2++='\\'; 292 | switch (token=*ptr++) 293 | { 294 | case '\\': *ptr2++='\\'; break; 295 | case '\"': *ptr2++='\"'; break; 296 | case '\b': *ptr2++='b'; break; 297 | case '\f': *ptr2++='f'; break; 298 | case '\n': *ptr2++='n'; break; 299 | case '\r': *ptr2++='r'; break; 300 | case '\t': *ptr2++='t'; break; 301 | default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */ 302 | } 303 | } 304 | } 305 | *ptr2++='\"';*ptr2++=0; 306 | return out; 307 | } 308 | /* Invote print_string_ptr (which is useful) on an item. */ 309 | static char *print_string(cJSON *item,printbuffer *p) {return print_string_ptr(item->valuestring,p);} 310 | 311 | /* Predeclare these prototypes. */ 312 | static const char *parse_value(cJSON *item,const char *value); 313 | static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p); 314 | static const char *parse_array(cJSON *item,const char *value); 315 | static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p); 316 | static const char *parse_object(cJSON *item,const char *value); 317 | static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p); 318 | 319 | /* Utility to jump whitespace and cr/lf */ 320 | static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;} 321 | 322 | /* Parse an object - create a new root, and populate. */ 323 | cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated) 324 | { 325 | const char *end=0; 326 | cJSON *c=cJSON_New_Item(); 327 | ep=0; 328 | if (!c) return 0; /* memory fail */ 329 | 330 | end=parse_value(c,skip(value)); 331 | if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */ 332 | 333 | /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ 334 | if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}} 335 | if (return_parse_end) *return_parse_end=end; 336 | return c; 337 | } 338 | /* Default options for cJSON_Parse */ 339 | cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);} 340 | 341 | /* Render a cJSON item/entity/structure to text. */ 342 | char *cJSON_Print(cJSON *item) {return print_value(item,0,1,0);} 343 | char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0,0);} 344 | 345 | char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt) 346 | { 347 | printbuffer p; 348 | p.buffer=(char*)cJSON_malloc(prebuffer); 349 | p.length=prebuffer; 350 | p.offset=0; 351 | return print_value(item,0,fmt,&p); 352 | return p.buffer; 353 | } 354 | 355 | 356 | /* Parser core - when encountering text, process appropriately. */ 357 | static const char *parse_value(cJSON *item,const char *value) 358 | { 359 | if (!value) return 0; /* Fail on null. */ 360 | if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; } 361 | if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; } 362 | if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; } 363 | if (*value=='\"') { return parse_string(item,value); } 364 | if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); } 365 | if (*value=='[') { return parse_array(item,value); } 366 | if (*value=='{') { return parse_object(item,value); } 367 | 368 | ep=value;return 0; /* failure. */ 369 | } 370 | 371 | /* Render a value to text. */ 372 | static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p) 373 | { 374 | char *out=0; 375 | if (!item) return 0; 376 | if (p) 377 | { 378 | switch ((item->type)&255) 379 | { 380 | case cJSON_NULL: {out=ensure(p,5); if (out) strcpy(out,"null"); break;} 381 | case cJSON_False: {out=ensure(p,6); if (out) strcpy(out,"false"); break;} 382 | case cJSON_True: {out=ensure(p,5); if (out) strcpy(out,"true"); break;} 383 | case cJSON_Number: out=print_number(item,p);break; 384 | case cJSON_String: out=print_string(item,p);break; 385 | case cJSON_Array: out=print_array(item,depth,fmt,p);break; 386 | case cJSON_Object: out=print_object(item,depth,fmt,p);break; 387 | } 388 | } 389 | else 390 | { 391 | switch ((item->type)&255) 392 | { 393 | case cJSON_NULL: out=cJSON_strdup("null"); break; 394 | case cJSON_False: out=cJSON_strdup("false");break; 395 | case cJSON_True: out=cJSON_strdup("true"); break; 396 | case cJSON_Number: out=print_number(item,0);break; 397 | case cJSON_String: out=print_string(item,0);break; 398 | case cJSON_Array: out=print_array(item,depth,fmt,0);break; 399 | case cJSON_Object: out=print_object(item,depth,fmt,0);break; 400 | } 401 | } 402 | return out; 403 | } 404 | 405 | /* Build an array from input text. */ 406 | static const char *parse_array(cJSON *item,const char *value) 407 | { 408 | cJSON *child; 409 | if (*value!='[') {ep=value;return 0;} /* not an array! */ 410 | 411 | item->type=cJSON_Array; 412 | value=skip(value+1); 413 | if (*value==']') return value+1; /* empty array. */ 414 | 415 | item->child=child=cJSON_New_Item(); 416 | if (!item->child) return 0; /* memory fail */ 417 | value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */ 418 | if (!value) return 0; 419 | 420 | while (*value==',') 421 | { 422 | cJSON *new_item; 423 | if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ 424 | child->next=new_item;new_item->prev=child;child=new_item; 425 | value=skip(parse_value(child,skip(value+1))); 426 | if (!value) return 0; /* memory fail */ 427 | } 428 | 429 | if (*value==']') return value+1; /* end of array */ 430 | ep=value;return 0; /* malformed. */ 431 | } 432 | 433 | /* Render an array to text */ 434 | static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p) 435 | { 436 | char **entries; 437 | char *out=0,*ptr,*ret;int len=5; 438 | cJSON *child=item->child; 439 | int numentries=0,i=0,fail=0; 440 | size_t tmplen=0; 441 | 442 | /* How many entries in the array? */ 443 | while (child) numentries++,child=child->next; 444 | /* Explicitly handle numentries==0 */ 445 | if (!numentries) 446 | { 447 | if (p) out=ensure(p,3); 448 | else out=(char*)cJSON_malloc(3); 449 | if (out) strcpy(out,"[]"); 450 | return out; 451 | } 452 | 453 | if (p) 454 | { 455 | /* Compose the output array. */ 456 | i=p->offset; 457 | ptr=ensure(p,1);if (!ptr) return 0; *ptr='['; p->offset++; 458 | child=item->child; 459 | while (child && !fail) 460 | { 461 | print_value(child,depth+1,fmt,p); 462 | p->offset=update(p); 463 | if (child->next) {len=fmt?2:1;ptr=ensure(p,len+1);if (!ptr) return 0;*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;p->offset+=len;} 464 | child=child->next; 465 | } 466 | ptr=ensure(p,2);if (!ptr) return 0; *ptr++=']';*ptr=0; 467 | out=(p->buffer)+i; 468 | } 469 | else 470 | { 471 | /* Allocate an array to hold the values for each */ 472 | entries=(char**)cJSON_malloc(numentries*sizeof(char*)); 473 | if (!entries) return 0; 474 | memset(entries,0,numentries*sizeof(char*)); 475 | /* Retrieve all the results: */ 476 | child=item->child; 477 | while (child && !fail) 478 | { 479 | ret=print_value(child,depth+1,fmt,0); 480 | entries[i++]=ret; 481 | if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1; 482 | child=child->next; 483 | } 484 | 485 | /* If we didn't fail, try to malloc the output string */ 486 | if (!fail) out=(char*)cJSON_malloc(len); 487 | /* If that fails, we fail. */ 488 | if (!out) fail=1; 489 | 490 | /* Handle failure. */ 491 | if (fail) 492 | { 493 | for (i=0;itype=cJSON_Object; 520 | value=skip(value+1); 521 | if (*value=='}') return value+1; /* empty array. */ 522 | 523 | item->child=child=cJSON_New_Item(); 524 | if (!item->child) return 0; 525 | value=skip(parse_string(child,skip(value))); 526 | if (!value) return 0; 527 | child->string=child->valuestring;child->valuestring=0; 528 | if (*value!=':') {ep=value;return 0;} /* fail! */ 529 | value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ 530 | if (!value) return 0; 531 | 532 | while (*value==',') 533 | { 534 | cJSON *new_item; 535 | if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ 536 | child->next=new_item;new_item->prev=child;child=new_item; 537 | value=skip(parse_string(child,skip(value+1))); 538 | if (!value) return 0; 539 | child->string=child->valuestring;child->valuestring=0; 540 | if (*value!=':') {ep=value;return 0;} /* fail! */ 541 | value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ 542 | if (!value) return 0; 543 | } 544 | 545 | if (*value=='}') return value+1; /* end of array */ 546 | ep=value;return 0; /* malformed. */ 547 | } 548 | 549 | /* Render an object to text. */ 550 | static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p) 551 | { 552 | char **entries=0,**names=0; 553 | char *out=0,*ptr,*ret,*str;int len=7,i=0,j; 554 | cJSON *child=item->child; 555 | int numentries=0,fail=0; 556 | size_t tmplen=0; 557 | /* Count the number of entries. */ 558 | while (child) numentries++,child=child->next; 559 | /* Explicitly handle empty object case */ 560 | if (!numentries) 561 | { 562 | if (p) out=ensure(p,fmt?depth+4:3); 563 | else out=(char*)cJSON_malloc(fmt?depth+4:3); 564 | if (!out) return 0; 565 | ptr=out;*ptr++='{'; 566 | if (fmt) {*ptr++='\n';for (i=0;ioffset; 574 | len=fmt?2:1; ptr=ensure(p,len+1); if (!ptr) return 0; 575 | *ptr++='{'; if (fmt) *ptr++='\n'; *ptr=0; p->offset+=len; 576 | child=item->child;depth++; 577 | while (child) 578 | { 579 | if (fmt) 580 | { 581 | ptr=ensure(p,depth); if (!ptr) return 0; 582 | for (j=0;joffset+=depth; 584 | } 585 | print_string_ptr(child->string,p); 586 | p->offset=update(p); 587 | 588 | len=fmt?2:1; 589 | ptr=ensure(p,len); if (!ptr) return 0; 590 | *ptr++=':';if (fmt) *ptr++='\t'; 591 | p->offset+=len; 592 | 593 | print_value(child,depth,fmt,p); 594 | p->offset=update(p); 595 | 596 | len=(fmt?1:0)+(child->next?1:0); 597 | ptr=ensure(p,len+1); if (!ptr) return 0; 598 | if (child->next) *ptr++=','; 599 | if (fmt) *ptr++='\n';*ptr=0; 600 | p->offset+=len; 601 | child=child->next; 602 | } 603 | ptr=ensure(p,fmt?(depth+1):2); if (!ptr) return 0; 604 | if (fmt) for (i=0;ibuffer)+i; 607 | } 608 | else 609 | { 610 | /* Allocate space for the names and the objects */ 611 | entries=(char**)cJSON_malloc(numentries*sizeof(char*)); 612 | if (!entries) return 0; 613 | names=(char**)cJSON_malloc(numentries*sizeof(char*)); 614 | if (!names) {cJSON_free(entries);return 0;} 615 | memset(entries,0,sizeof(char*)*numentries); 616 | memset(names,0,sizeof(char*)*numentries); 617 | 618 | /* Collect all the results into our arrays: */ 619 | child=item->child;depth++;if (fmt) len+=depth; 620 | while (child) 621 | { 622 | names[i]=str=print_string_ptr(child->string,0); 623 | entries[i++]=ret=print_value(child,depth,fmt,0); 624 | if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1; 625 | child=child->next; 626 | } 627 | 628 | /* Try to allocate the output string */ 629 | if (!fail) out=(char*)cJSON_malloc(len); 630 | if (!out) fail=1; 631 | 632 | /* Handle failure */ 633 | if (fail) 634 | { 635 | for (i=0;ichild;int i=0;while(c)i++,c=c->next;return i;} 662 | cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;} 663 | cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} 664 | 665 | /* Utility for array list handling. */ 666 | static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;} 667 | /* Utility for handling references. */ 668 | static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;} 669 | 670 | /* Add item to array/object. */ 671 | void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}} 672 | void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);} 673 | void cJSON_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (!(item->type&cJSON_StringIsConst) && item->string) cJSON_free(item->string);item->string=(char*)string;item->type|=cJSON_StringIsConst;cJSON_AddItemToArray(object,item);} 674 | void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));} 675 | void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));} 676 | 677 | cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0; 678 | if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;} 679 | void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));} 680 | cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;} 681 | void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));} 682 | 683 | /* Replace array/object items with new ones. */ 684 | void cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) {cJSON_AddItemToArray(array,newitem);return;} 685 | newitem->next=c;newitem->prev=c->prev;c->prev=newitem;if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;} 686 | void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return; 687 | newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem; 688 | if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);} 689 | void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}} 690 | 691 | /* Create basic types: */ 692 | cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;} 693 | cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;} 694 | cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;} 695 | cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;} 696 | cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;} 697 | cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;} 698 | cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;} 699 | cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} 700 | 701 | /* Create Arrays: */ 702 | cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} 703 | cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} 704 | cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} 705 | cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} 706 | 707 | /* Duplication */ 708 | cJSON *cJSON_Duplicate(cJSON *item,int recurse) 709 | { 710 | cJSON *newitem,*cptr,*nptr=0,*newchild; 711 | /* Bail on bad ptr */ 712 | if (!item) return 0; 713 | /* Create new item */ 714 | newitem=cJSON_New_Item(); 715 | if (!newitem) return 0; 716 | /* Copy over all vars */ 717 | newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble; 718 | if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}} 719 | if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}} 720 | /* If non-recursive, then we're done! */ 721 | if (!recurse) return newitem; 722 | /* Walk the ->next chain for the child. */ 723 | cptr=item->child; 724 | while (cptr) 725 | { 726 | newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */ 727 | if (!newchild) {cJSON_Delete(newitem);return 0;} 728 | if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */ 729 | else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */ 730 | cptr=cptr->next; 731 | } 732 | return newitem; 733 | } 734 | 735 | void cJSON_Minify(char *json) 736 | { 737 | char *into=json; 738 | while (*json) 739 | { 740 | if (*json==' ') json++; 741 | else if (*json=='\t') json++; /* Whitespace characters. */ 742 | else if (*json=='\r') json++; 743 | else if (*json=='\n') json++; 744 | else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; /* double-slash comments, to end of line. */ 745 | else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} /* multiline comments. */ 746 | else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} /* string literals, which are \" sensitive. */ 747 | else *into++=*json++; /* All other characters. */ 748 | } 749 | *into=0; /* and null-terminate. */ 750 | } 751 | -------------------------------------------------------------------------------- /core/robot-tuling/cJSON.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Dave Gamble 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #ifndef cJSON__h 24 | #define cJSON__h 25 | 26 | #ifdef __cplusplus 27 | extern "C" 28 | { 29 | #endif 30 | 31 | /* cJSON Types: */ 32 | #define cJSON_False 0 33 | #define cJSON_True 1 34 | #define cJSON_NULL 2 35 | #define cJSON_Number 3 36 | #define cJSON_String 4 37 | #define cJSON_Array 5 38 | #define cJSON_Object 6 39 | 40 | #define cJSON_IsReference 256 41 | #define cJSON_StringIsConst 512 42 | 43 | /* The cJSON structure: */ 44 | typedef struct cJSON { 45 | struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ 46 | struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ 47 | 48 | int type; /* The type of the item, as above. */ 49 | 50 | char *valuestring; /* The item's string, if type==cJSON_String */ 51 | int valueint; /* The item's number, if type==cJSON_Number */ 52 | double valuedouble; /* The item's number, if type==cJSON_Number */ 53 | 54 | char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ 55 | } cJSON; 56 | 57 | typedef struct cJSON_Hooks { 58 | void *(*malloc_fn)(size_t sz); 59 | void (*free_fn)(void *ptr); 60 | } cJSON_Hooks; 61 | 62 | /* Supply malloc, realloc and free functions to cJSON */ 63 | extern void cJSON_InitHooks(cJSON_Hooks* hooks); 64 | 65 | 66 | /* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ 67 | extern cJSON *cJSON_Parse(const char *value); 68 | /* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ 69 | extern char *cJSON_Print(cJSON *item); 70 | /* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ 71 | extern char *cJSON_PrintUnformatted(cJSON *item); 72 | /* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ 73 | extern char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt); 74 | /* Delete a cJSON entity and all subentities. */ 75 | extern void cJSON_Delete(cJSON *c); 76 | 77 | /* Returns the number of items in an array (or object). */ 78 | extern int cJSON_GetArraySize(cJSON *array); 79 | /* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ 80 | extern cJSON *cJSON_GetArrayItem(cJSON *array,int item); 81 | /* Get item "string" from object. Case insensitive. */ 82 | extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); 83 | 84 | /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ 85 | extern const char *cJSON_GetErrorPtr(void); 86 | 87 | /* These calls create a cJSON item of the appropriate type. */ 88 | extern cJSON *cJSON_CreateNull(void); 89 | extern cJSON *cJSON_CreateTrue(void); 90 | extern cJSON *cJSON_CreateFalse(void); 91 | extern cJSON *cJSON_CreateBool(int b); 92 | extern cJSON *cJSON_CreateNumber(double num); 93 | extern cJSON *cJSON_CreateString(const char *string); 94 | extern cJSON *cJSON_CreateArray(void); 95 | extern cJSON *cJSON_CreateObject(void); 96 | 97 | /* These utilities create an Array of count items. */ 98 | extern cJSON *cJSON_CreateIntArray(const int *numbers,int count); 99 | extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count); 100 | extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count); 101 | extern cJSON *cJSON_CreateStringArray(const char **strings,int count); 102 | 103 | /* Append item to the specified array/object. */ 104 | extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); 105 | extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item); 106 | extern void cJSON_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item); /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object */ 107 | /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ 108 | extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); 109 | extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item); 110 | 111 | /* Remove/Detatch items from Arrays/Objects. */ 112 | extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which); 113 | extern void cJSON_DeleteItemFromArray(cJSON *array,int which); 114 | extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string); 115 | extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string); 116 | 117 | /* Update array items. */ 118 | extern void cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem); /* Shifts pre-existing items to the right. */ 119 | extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem); 120 | extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); 121 | 122 | /* Duplicate a cJSON item */ 123 | extern cJSON *cJSON_Duplicate(cJSON *item,int recurse); 124 | /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will 125 | need to be released. With recurse!=0, it will duplicate any children connected to the item. 126 | The item->next and ->prev pointers are always zero on return from Duplicate. */ 127 | 128 | /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ 129 | extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated); 130 | 131 | extern void cJSON_Minify(char *json); 132 | 133 | /* Macros for creating things quickly. */ 134 | #define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) 135 | #define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) 136 | #define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) 137 | #define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) 138 | #define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) 139 | #define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) 140 | 141 | /* When assigning an integer value, it needs to be propagated to valuedouble too. */ 142 | #define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val)) 143 | #define cJSON_SetNumberValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val)) 144 | 145 | #ifdef __cplusplus 146 | } 147 | #endif 148 | 149 | #endif 150 | -------------------------------------------------------------------------------- /core/robot-tuling/tuling-cli.c: -------------------------------------------------------------------------------- 1 | /* QRobot Project By Ljk 2 | * 2016-01-17 3 | */ 4 | 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "cJSON.h" 11 | 12 | #define TULING_URL "http://www.tuling123.com/openapi/api" 13 | #define APIKEY_PATH "./settings.cfg" 14 | 15 | void doit(char *text) 16 | { 17 | cJSON *json; 18 | 19 | json = cJSON_Parse(text); 20 | if (!json) { 21 | printf("Error before: [%s]\n", cJSON_GetErrorPtr()); 22 | } else { 23 | int code = cJSON_GetObjectItem(json, "code")->valueint; 24 | // printf("Code is %d\n", code); 25 | char *text, *url; 26 | switch(code) { 27 | case 100000: 28 | text = cJSON_GetObjectItem(json, "text")->valuestring; 29 | printf("@%s\n", text); 30 | break; 31 | case 200000: 32 | text = cJSON_GetObjectItem(json, "text")->valuestring; 33 | url = cJSON_GetObjectItem(json, "url")->valuestring; 34 | printf("@%s\n%s\n", text, url); 35 | break; 36 | case 40001: 37 | case 40003: 38 | fprintf(stderr, "Keys error, changing to old version robot\n"); 39 | exit(3); 40 | case 40004: 41 | fprintf(stderr, "Visit Limit\n"); 42 | exit(4); 43 | } 44 | } 45 | } 46 | 47 | 48 | size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata) 49 | { 50 | // printf("Got \n%s\n", ptr); 51 | doit(ptr); 52 | return size*nmemb; 53 | } 54 | 55 | 56 | char *get_apikey() 57 | { 58 | FILE *fp = fopen(APIKEY_PATH, "r"); 59 | if(fp == NULL) { 60 | fprintf(stderr,"Error Get apikey file\n"); 61 | } 62 | char *apikey = (char *) malloc(100); 63 | fgets(apikey, 100, fp); 64 | int i; 65 | for (i = 0; apikey[i] != '\n'; i++) { 66 | } 67 | apikey[i] = '\0'; 68 | return apikey; 69 | } 70 | 71 | char *combine_data(char *str1, char *str2, char *str3) 72 | { 73 | char *post_data = (char *) malloc(2048); 74 | memset(post_data, 0, 2048); 75 | strcpy(post_data, "key="); 76 | strcat(post_data, str1); 77 | strcat(post_data, "&userid="); 78 | strcat(post_data, str2); 79 | strcat(post_data, "&info="); 80 | strcat(post_data, str3); 81 | return post_data; 82 | } 83 | 84 | // 图灵新API要求POST方式 85 | int httpost(char *apikey, char *userid, char *text) 86 | { 87 | CURL *curl; 88 | CURLcode res; 89 | char *post_data = combine_data(apikey, userid, text); 90 | // Debug 91 | // printf("Post Data %s\n", post_data); 92 | // 93 | curl_global_init(CURL_GLOBAL_ALL); 94 | curl = curl_easy_init(); 95 | if (curl) { 96 | curl_easy_setopt(curl, CURLOPT_URL, TULING_URL); 97 | curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data); 98 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); 99 | // Debug 100 | // printf("Starting... GET\n"); 101 | // 102 | res = curl_easy_perform(curl); 103 | if (res != CURLE_OK) { 104 | fprintf(stderr, "curl_easy_perform() failed: %s\n", 105 | curl_easy_strerror(res)); 106 | curl_global_cleanup(); 107 | return -1; 108 | } 109 | } 110 | return 1; 111 | } 112 | 113 | int main(int argc, char **argv) 114 | { 115 | if (argc < 3) { 116 | fprintf(stderr, "%s [Json file path]", argv[0]); 117 | return 1; 118 | } 119 | 120 | httpost(get_apikey(), argv[1], argv[2]); 121 | // printf("%s\n", combine_data(get_apikey(), argv[2], argv[3])); 122 | return 0; 123 | } 124 | -------------------------------------------------------------------------------- /core/robot.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | # QRobot Project By Ljkgpxs 3 | 4 | # $uid is fromer QQ number 5 | # $context is message content 6 | 7 | # $1 message type; $2 Fromer QQ number; $3 message content 8 | #cd ./core/ 9 | ################### 10 | . ./conf/env 11 | 12 | if [ -f ./qqlog.txt ]; then 13 | : 14 | else 15 | touch ./qqlog.txt 16 | fi 17 | 18 | export uid=$2 19 | export context=$3 20 | 21 | same="$robot_dir/same" 22 | errfile="$robot_dir/err.lst" 23 | lognum=0 24 | other=0 25 | function check_err 26 | { 27 | # echo "Start $PWD $1" 28 | $same "$1" $errfile 29 | ret=$? 30 | # echo "Return code $ret" 31 | if [ $ret != 0 ] 32 | then 33 | echo "不要说脏话哦!" 34 | fi 35 | } 36 | 37 | 38 | function func 39 | { 40 | lognum=`grep $uid qqlog.txt | wc -l` 41 | special_list=`grep $uid ./conf/special_list.txt | wc -l` 42 | 43 | if [ "${context:0:1}" == "@" ] || [ "${context:0:1}" == "@" ]; then 44 | if [ -z ${context:1} ] 45 | then 46 | echo "您要说什么呢?" 47 | else 48 | # echo "${context:1}" 49 | case "${context:1}" in 50 | "/tmp/robot_shell.sh 60 | chmod 777 /tmp/robot_shell.sh 61 | /tmp/robot_shell.sh 62 | ret=$? 63 | rm /tmp/robot_shell.sh 64 | if [ $ret == 0 ]; then 65 | echo "Successful" 66 | else 67 | echo "Failed with $ret" 68 | fi 69 | fi 70 | ;; 71 | * ) 72 | # echo "Got Normal Message" 73 | if [ ! -s ./robot-tuling/settings.cfg ]; then 74 | $robot_dir/normal.sh "${context:1}" 75 | else 76 | cd robot-tuling 77 | ./test $uid ${context:1} 78 | if [ $? != 0 ]; then 79 | cd ../ 80 | $robot_dir/normal.sh "${context:1}" 81 | fi 82 | fi 83 | ;; 84 | esac 85 | fi 86 | 87 | else 88 | # echo "Push to robot" 89 | case "$context" in 90 | \?*-* | ?*-*) 91 | $robot_dir/study.sh "$context";; 92 | * ) 93 | # echo lognum $lognum special_list $special_list 94 | if [ $lognum == 0 ] && [ $special_list == 0 ] 95 | then 96 | echo "您好,我是机器人-妹抖. 97 | 如果想和我聊天,可以在消息前面加上@哦!" 98 | check_err "$context" 99 | else 100 | check_err "$context" 101 | if [ $lognum == 5 ] 102 | then 103 | echo "主人真的不在啦,妹抖从来都不骗人的说,不介意的话就和我聊天嘛! 104 | 消息前面不要忘了加@哦!" 105 | fi 106 | fi 107 | echo $uid >>./qqlog.txt;; 108 | esac 109 | fi 110 | exit 0 111 | } 112 | 113 | func 114 | -------------------------------------------------------------------------------- /core/robot/allow.lst: -------------------------------------------------------------------------------- 1 | # 写下管理员QQ号,以使用机器人的模糊学习功能 2 | -------------------------------------------------------------------------------- /core/robot/ans.txt: -------------------------------------------------------------------------------- 1 | 调教指令: ?问题-答案 ,例如: ?你叫什么-我叫妹抖啦! 指令中的符号是英文的问号和减号哦! 问题中间和问号前也不要带空格哦! 不要教伦家骂人哦,不然主人会惩罚play的说! 2 | 调教指令: ?问题-答案 ,例如: ?你叫什么-我叫妹抖啦! 指令中的符号是英文的问号和减号哦! 问题中间和问号前也不要带空格哦! 不要教伦家骂人哦,不然主人会惩罚play的说! 3 | 调教指令: ?问题-答案 ,例如: ?你叫什么-我叫妹抖啦! 指令中的符号是英文的问号和减号哦! 问题中间和问号前也不要带空格哦! 不要教伦家骂人哦,不然主人会惩罚play的说! 4 | 调教指令: ?问题-答案 ,例如: ?你叫什么-我叫妹抖啦! 指令中的符号是英文的问号和减号哦! 问题中间和问号前也不要带空格哦! 不要教伦家骂人哦,不然主人会惩罚play的说! 5 | 调教指令: ?问题-答案 ,例如: ?你叫什么-我叫妹抖啦! 指令中的符号是英文的问号和减号哦! 问题中间和问号前也不要带空格哦! 不要教伦家骂人哦,不然主人会惩罚play的说! 6 | 调教指令: ?问题-答案 ,例如: ?你叫什么-我叫妹抖啦! 指令中的符号是英文的问号和减号哦! 问题中间和问号前也不要带空格哦! 不要教伦家骂人哦,不然主人会惩罚play的说! 7 | 调教指令: ?问题-答案 ,例如: ?你叫什么-我叫妹抖啦! 指令中的符号是英文的问号和减号哦! 问题中间和问号前也不要带空格哦! 不要教伦家骂人哦,不然主人会惩罚play的说! 8 | 调教指令: ?问题-答案 ,例如: ?你叫什么-我叫妹抖啦! 指令中的符号是英文的问号和减号哦! 问题中间和问号前也不要带空格哦! 不要教伦家骂人哦,不然主人会惩罚play的说! 9 | 调教指令: ?问题-答案 ,例如: ?你叫什么-我叫妹抖啦! 指令中的符号是英文的问号和减号哦! 问题中间和问号前也不要带空格哦! 不要教伦家骂人哦,不然主人会惩罚play的说! 10 | 有问题吗? 11 | 做个好孩子,不要骂人哦! 12 | 干嘛骂我嘞!!我要向主人告状!! 13 | 不要叫主人外号啦! 14 | 恩, 知错就是好孩子! 15 | 我在帮主人挂QQ呀! 16 | 我在帮主人挂QQ呀! 17 | 逗你? 18 | 不要骂人的啦! 19 | 很好笑吗? 20 | 骂人是不好的吆!! 21 | 骂人不是好孩纸哦!! 22 | 孩纸乖,不要骂人! 23 | 好孩纸不要说脏话哦! 24 | 我?没事干啊。。。 25 | 伦家才不告诉你呢! 26 | 我妹?伦家还没有妹妹的说! 27 | 好啊:) 28 | 我是妹抖哦! 29 | 么么哒 30 | 卖萌啦~\(≧▽≦)/~ 31 | 我是人见人爱的妹抖啦= ̄ω ̄= 32 | #date +%H:%M:%S 33 | #date +%Y年%m月%d日 34 | #date +%Y年%m月%d日 35 | 你是大坏蛋 36 | 滚..滚...滚...我又滚回来了 37 | 因为我是通过网页和你聊天呀!所以比较慢啦! 38 | 不告诉你,你是坏蛋! 39 | 伦家才不告诉你呢^ω^ 40 | 不告诉你23333 41 | 瞄准!发射!OPPS!不好意思.打偏了~ 42 | 是的呦! 43 | 是的黝! 44 | 是的呦! 45 | 是的呦! 46 | 必须的必呀! 47 | 哈哈! 48 | 有点好笑。。 49 | 没什么~ 50 | 没啥~ 51 | 我妹抖哦~ 52 | 你在调戏我吗? 53 | 笑什么呢? 54 | 就告诉我嘛! 55 | 不行就算了~ 56 | 你好小气哦! 57 | 你猜我知道吗? 58 | 你就猜一猜啊! 59 | 你这人好没劲啊! 60 | 好吧。。。 61 | 那你慢慢笑!我听着好了! 62 | 叫那么好听,喜欢上我了吗 63 | 再见啦!下次再聊吧! 64 | 瓜皮先生的说! 65 | 我当然漂亮啦!啦啦啦!~\(≧▽≦)/~ 66 | 没我漂亮→_→ 67 | 不要介意嘛!我反应少于迟钝的说→_→ 68 | 你骂人了!你是大坏蛋! 69 | 你笑得好开心啊! 70 | 泥嚎呀! 71 | 泥嚎呀o(≧v≦)o 72 | 在呢在呢o(≧v≦)o 73 | 在啊~\(≧▽≦)/~ 74 | 来啦,来啦! 75 | 来啦来啦(>^ω^<) 76 | 你怎么知道的w(□Д□)w 77 | 你怎么知道的w(□Д□)w 78 | 我就素傻傻的呀≡ω≡ 79 | 泥嚎呀⊙▽⊙ 80 | #if [ 1 == 2 ]; then echo $uid; else echo Tested $uid; fi 81 | 你说你素谁呢,小笨蛋= ̄ω ̄= 82 | 你说你是谁呢,小笨蛋~\(≧▽≦)/~ 83 | 你就素笨蛋,你就素笨蛋o(≧v≦)o 84 | 唉~你是机器人,妹抖不理你了╭(╯ε╰)╮ 85 | 你才素笨!我主银是天才= ̄ω ̄= 86 | #uptime 87 | :grin: 88 | #listFriends 89 | -------------------------------------------------------------------------------- /core/robot/ans_abs.txt: -------------------------------------------------------------------------------- 1 | Computer_Programming 2 | 您的意思是如何调教吗?那请您输入:@怎么调教? 3 | 您的意思是如何调教吗?那请您输入:@怎么调教? 4 | 您的意思是如何调教吗?那请您输入:@怎么调教? 5 | 您的意思是如何调教吗?那请您输入:@怎么调教? 6 | 您的意思是如何调教吗?那请您输入:@怎么调教? 7 | 您的意思是如何调教吗?那请您输入:@怎么调教? 8 | 西瓜 9 | 哈喽!~\(≧▽≦)/~ 10 | 咪! 11 | 好啊= ̄ω ̄= 12 | HI~ 13 | Hello! 14 | 怎么了? 15 | 呵呵→_→ 16 | 你笑的好开心! 17 | 尽情的调戏吧~\(≧▽≦)/~ 18 | 泥嚎啊≡ω≡ 19 | 对啊,我主银就素个大笨蛋 20 | 天气真好 21 | 你还是逗比! 22 | 你妹的。。 23 | ....... 24 | ..... 25 | 哈 26 | ... 27 | ... 28 | .... 29 | 。。。 30 | 。。。 31 | Hello! 32 | -------------------------------------------------------------------------------- /core/robot/err.lst: -------------------------------------------------------------------------------- 1 | ** 2 | sb 3 | Sb 4 | SB 5 | 我擦 6 | 贱逼 7 | 贱婢 8 | 你妹 9 | 擦,你,妹 10 | 操,你,妹 11 | 操,你,妈 12 | 尼,玛 13 | 你,妹.的 14 | 草,泥,马 15 | 你,大,爷 16 | 王八 17 | 驴熊 18 | 不是,好东西 19 | fuck 20 | Fuck 21 | FUCK 22 | fUck 23 | FUck 24 | FUCk 25 | fuCk 26 | fucK 27 | shit 28 | Shit 29 | Bugger 30 | bugger 31 | -------------------------------------------------------------------------------- /core/robot/findans.c: -------------------------------------------------------------------------------- 1 | /* QRobot Project By Ljkgpxs */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define LONG 3*300 9 | 10 | int main(int argc, char **argv) 11 | { 12 | if(argc < 3) 13 | return 0; 14 | int line = atoi(argv[1]); 15 | FILE *afile = fopen(argv[2], "r"); 16 | if(afile == NULL) 17 | return 1; 18 | int cur; 19 | char *ans = (char *)malloc(LONG); 20 | for(cur = 1; cur <= line; cur++) { 21 | ans = fgets(ans, LONG, afile); 22 | if(ans == NULL && cur != line-1) 23 | return 0; 24 | } 25 | printf("%s", ans); 26 | return line; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /core/robot/getdata.c: -------------------------------------------------------------------------------- 1 | /* QRobot Project By Ljkgpxs */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main(int argc, char **argv) 8 | { 9 | if(argc < 3){ 10 | fprintf(stderr, "Give Me The Strings\n"); 11 | return 1; 12 | } 13 | 14 | 15 | char *str = (char *)malloc(3*300); 16 | int i, k; 17 | if(argv[2][0] == '1'){ // Get the Question 18 | if(argv[1][0] == '?') 19 | i=1; 20 | else 21 | i=3; 22 | for(k=0; i < strlen(argv[1]); i++, k++){ 23 | if(argv[1][i] == '-'){ 24 | str[k] = '\0'; 25 | printf("%s", str); 26 | return 0; 27 | } else { 28 | // printf("%s", str); 29 | str[k] = argv[1][i]; 30 | } 31 | } 32 | } 33 | else if(argv[2][0] == '2'){ //Get the Ans 34 | int s=0; 35 | for(i=1, k=0; i < strlen(argv[1]); i++, k++){ 36 | if(s == 1){ 37 | str[k] = argv[1][i]; 38 | } 39 | if(argv[1][i] == '-') { 40 | s=1; 41 | k=-1; 42 | } 43 | } 44 | str[k] = '\0'; 45 | printf("%s", str); 46 | return 0; 47 | } 48 | return 0; 49 | 50 | } 51 | 52 | 53 | -------------------------------------------------------------------------------- /core/robot/normal.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # QRobot Project By Ljkgpxs 3 | 4 | cd $robot_dir 5 | 6 | qfile="./ques.txt" 7 | afile="./ans.txt" 8 | 9 | 10 | # 检查是否有脏话 使用模糊搜索 11 | ./same "$@" ./err.lst 12 | if [ $? != 0 ] 13 | then 14 | echo "骂人的孩纸不是好好孩纸~" 15 | exit 0 16 | fi 17 | 18 | # 搜索问题 使用绝对搜索 绝对数据由用户添加 19 | ./same_abs "$@" ./ques_abs.txt 20 | ret=$? 21 | if [ $ret != 0 ] 22 | then 23 | echo "`./findans $ret ./ans_abs.txt`" 24 | exit 0; 25 | fi 26 | 27 | # 搜索问题 使用模糊搜索,模糊数据由管理员管理 28 | ./same "$@" $qfile 29 | ans="`./findans $? $afile `" 30 | 31 | if [ $? == 0 ] 32 | then 33 | echo "妹抖不理解您的意思,可以教我吗?" 34 | echo "教我的方法可以问我哦!" 35 | else 36 | if [ ${ans:0:1} == '#' ] 37 | then 38 | echo ${ans:1} >/tmp/"$uid"_bashqq.cmd 39 | chmod 775 /tmp/"$uid"_bashqq.cmd 40 | bash /tmp/"$uid"_bashqq.cmd 41 | rm /tmp/"$uid"_bashqq.cmd 42 | else 43 | echo "$ans" 44 | fi 45 | fi 46 | 47 | -------------------------------------------------------------------------------- /core/robot/ques.txt: -------------------------------------------------------------------------------- 1 | 咋,教你 2 | 咋,调教 3 | 咋,学习 4 | 怎,教你 5 | 怎,学习 6 | 如何,教你 7 | 如何,学习 8 | 怎,调教 9 | 如何,调教 10 | 怎么,这样 11 | ** 12 | sb 13 | 贱婢 14 | 我错了 15 | 你,干,嘛 16 | 你,干,吗 17 | 逗比 18 | 你妹 19 | 哈哈 20 | 擦,你,妹 21 | 操,你,妹 22 | 操,你,妈 23 | 尼玛 24 | 你在,干,什么 25 | 你,干啥 26 | 你,妹.的 27 | 你好 28 | 你是谁 29 | 吆西 30 | 么么哒 31 | 你,叫什么 32 | 几点 33 | 日期 34 | 今天,几号 35 | 骂你怎么了 36 | 给,滚 37 | 你,反应慢 38 | 密码,多少 39 | 密码,什么 40 | 爸爸,谁,是 41 | 打,我,头 42 | 板子,登 43 | 板子,运行 44 | 开发板,登 45 | 开发板,运行 46 | 好叼 47 | 我,个去 48 | 好笑,吗 49 | 笑什么 50 | 笑啥 51 | 这是啥 52 | 哇咔咔 53 | 呜哈哈 54 | 没什么 55 | 不行 56 | 不告诉你 57 | 你知道,吗 58 | 我不猜 59 | 我就不猜 60 | 不好笑 61 | 好笑 62 | 妹抖妹抖 63 | 拜拜 64 | 主人,谁 65 | 你,漂亮 66 | 我,漂亮 67 | 速度,不,快 68 | 麻痹,的 69 | 2333 70 | 妹抖,泥嚎 71 | 机器人,泥嚎 72 | 妹抖,在吗 73 | 机器,在吗 74 | 机器,酱紫,粗来 75 | 妹抖,酱紫,粗来 76 | 你,笨蛋 77 | 你,笨蛋 78 | 你,傻傻的 79 | 泥嚎 80 | get,uid,var 81 | 我素谁 82 | 我是谁 83 | 我,不,笨蛋 84 | AUTO,script 85 | 你主人,好笨 86 | uptime 87 | 表情测试 88 | lstfrd 89 | -------------------------------------------------------------------------------- /core/robot/ques_abs.txt: -------------------------------------------------------------------------------- 1 | hello,world 2 | 调教? 3 | 调教? 4 | 调教 5 | 教你? 6 | 教你? 7 | 教你 8 | 谁是神 9 | 哈咯 10 | 喵 11 | 哈喽 12 | 哈啰 13 | 哈罗 14 | 我去 15 | 我勒个去 16 | 2333 17 | 调戏你 18 | 泥嚎啊 19 | 他好笨 20 | 你好 21 | 我是萌比 22 | 我是你爸比吗 23 | 居然不爱捡肥皂 24 | 为什么不爱捡肥皂 25 | 啊 26 | 我是你爸爸 27 | 真乖 28 | 肥皂掉了 29 | 呵呵 30 | 呵呵呵 31 | hello 32 | -------------------------------------------------------------------------------- /core/robot/same.c: -------------------------------------------------------------------------------- 1 | /* QRobot Project By Ljkgpxs */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(int argc, char **argv) 9 | { 10 | if(argc < 3) { 11 | // fprintf(stderr, "Give me a string\n"); 12 | return 0; 13 | } 14 | FILE *qfile = fopen(argv[2], "r"); 15 | if(qfile == NULL) { 16 | // fprintf(stderr, "Open Question File Failed\n"); 17 | return 0; 18 | } 19 | 20 | char *ques = (char *)malloc(100); 21 | int line=0; 22 | int siz, i, k; 23 | char *voc = (char *)malloc(2*5); 24 | while(feof(qfile) == 0) 25 | { 26 | ques = fgets(ques, 100, qfile); 27 | if(ques == NULL) 28 | break; 29 | line++; 30 | // printf("Ques : %s\n", ques); 31 | siz = strlen(ques) - 1; 32 | ques[siz] = '\0'; 33 | // printf("Find \"%s\" in \"%s\"\n", ques, argv[1]); 34 | for(i=0, k=0; i <= siz; i++, k++) { 35 | if(ques[i] == ',' || i == siz) { 36 | voc[k] = '\0'; 37 | // printf("Source %s, Vocbulary %s\nk=%d\n\n", argv[1], voc, k); 38 | if(strstr(argv[1], voc) == NULL) 39 | break; 40 | else if(i == siz) 41 | return line; 42 | k=0; 43 | i++; 44 | } 45 | voc[k] = ques[i]; 46 | } 47 | } 48 | free(ques); 49 | free(voc); 50 | return 0; 51 | } 52 | 53 | 54 | -------------------------------------------------------------------------------- /core/robot/same_abs.c: -------------------------------------------------------------------------------- 1 | /* QRobot Project By Ljkgpxs */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(int argc, char **argv) 9 | { 10 | if(argc < 3) { 11 | // fprintf(stderr, "Give me a string\n"); 12 | return 0; 13 | } 14 | FILE *qfile = fopen(argv[2], "r"); 15 | if(qfile == NULL) { 16 | // fprintf(stderr, "Open Question File Failed\n"); 17 | return 0; 18 | } 19 | 20 | char *ques = (char *)malloc(100); 21 | int line=0; 22 | int siz, i, k; 23 | char *voc = (char *)malloc(2*5); 24 | while(feof(qfile) == 0) 25 | { 26 | ques = fgets(ques, 100, qfile); 27 | if(ques == NULL) 28 | break; 29 | line++; 30 | // printf("Ques : %s\n", ques); 31 | siz = strlen(ques) - 1; 32 | ques[siz] = '\0'; 33 | // printf("Find \"%s\" in \"%s\"\n", ques, argv[1]); 34 | if(strcmp(argv[1], ques) == 0) 35 | return line; 36 | } 37 | free(ques); 38 | free(voc); 39 | return 0; 40 | } 41 | 42 | 43 | -------------------------------------------------------------------------------- /core/robot/study.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # QRobot Project By Ljkgpxs 3 | 4 | cd $robot_dir 5 | 6 | ques="`./getdata "$@" 1`" 7 | ans="`./getdata "$@" 2`" 8 | if [ -z $ques ] || [ -z $ans ] 9 | then 10 | echo "不要填写空白哦!" 11 | exit 0 12 | fi 13 | 14 | ./same "$ques" ./err.lst 15 | errq=`echo $?` 16 | ./same "$ans" ./err.lst 17 | erra=`echo $?` 18 | if [ $errq == 0 ] && [ $erra == 0 ] 19 | then 20 | : 21 | else 22 | echo "不允许骂人哦,妹抖是会学坏的说!" 23 | exit 0 24 | fi 25 | 26 | 27 | if [ `grep $uid ./allow.lst | wc -l` != 0 ] 28 | then 29 | ./same "$ques" ./ques.txt 30 | errq=`echo $?` 31 | if [ $errq == 0 ] 32 | then 33 | echo "$ques" >>./ques.txt 34 | echo "$ans" >>./ans.txt 35 | echo "妹抖记住啦!!!我的主人!" 36 | echo "问:$ques,答:$ans" 37 | else 38 | echo "妹抖已经会了,不用再教这个了!" 39 | fi 40 | else 41 | ./same_abs "$ques" ./ques_abs.txt 42 | errq=`echo $?` 43 | if [ $errq == 0 ] 44 | then 45 | echo "$ques" >>./ques_abs.txt 46 | echo "$ans" >>./ans_abs.txt 47 | echo "妹抖记住啦!" 48 | echo "问:$ques,答:$ans" 49 | else 50 | echo "妹抖已经会了,不用再教这个了!" 51 | fi 52 | fi 53 | exit 0 54 | 55 | -------------------------------------------------------------------------------- /core/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # QRobot Project By Ljkgpxs 3 | cd core 4 | #./robot.sh $1 $2 $3 5 | reply_content=`./robot.sh $1 $2 $3` 6 | echo -n $reply_content >/tmp/"$2".reply 7 | -------------------------------------------------------------------------------- /doc/robot.txt: -------------------------------------------------------------------------------- 1 | 关于机器人定制: 2 | 3 | 所有关于机器人的数据均储存于 'core/',目录切换至 'core/robot/' 4 | 即可看到,可修改此目录内文件和 'core/start.sh' 来实现定制 5 | 6 | 机器人具体流程 7 | 8 | login->client loop <--------------- 9 | | | 10 | on receive message | 11 | | | 12 | |(message data) | 13 | | | 14 | robot handle | 15 | | | 16 | |(reply message) | 17 | | | 18 | client thread -> send message 19 | 20 | 21 | 定制机器人就是修改robot的处理方式 22 | start.pl 23 | 会将收到的消息类型、消息的发送者、消息内容传接至robot部分,robot部分以 24 | core/start.sh开始,然后将上层传来的数据向机器人核心部分传送,即core/robot/normal.sh或core/robot/study.sh,normal.sh是用来处理一般消息的,study.sh用来学习新语句 25 | 26 | 27 | 处理消息分为大致两种,一种是管理员拥有的数据对比库,一种是普通用户拥有的数据对比库。管理员QQ号请写在core/robot/allow.lst 28 | 管理员的数据库采用模糊语法记录,问题记录的具体形式如下 29 | 关键词1,关键词2,关键词3.... 30 | 这会被储存在core/robot/ques.txt 31 | 相应的,每个问题也会有答案,并且答案文件中的行数,对应问题文件中的行数被储存于core/robot/ans.txt 32 | 33 | 模糊判断会根据ques.txt的记录进行消息的处理,ques.txt内每行都对应一个消息模板,例如小明给我发来消息: hello,my name is xiaoming 34 | 我就可以对关键语句进行提取,消息中含有'hello','name','xiaoming'词汇,根据这些词汇可以判断是小明打招呼,那么就可以这样记录进ques.txt 35 | hello,name,xiaoming 36 | 那么我就可以向机器人发送消息进行学习 37 | ?hello,name,xiaoming-Hello!XiaoMing! 38 | 39 | 另外,管理员可以用shell做二次消息处理,把shell写入ans.txt,并且语句头部分要有#这个字符,告诉机器人这是一个shell语句,一般通过QQ消息进行机器人学习,例如: 40 | ?现在,几点,啦-#date 41 | 42 | 43 | 相对的,普通用户数据库就很死板,问题库和答案库分别在core/robot/qes_abs.txt, 44 | core/robot/ans_abs.txt 45 | 机器人会根据普通用户库进行绝对比较,消息和问题库中的数据不能相差一个字符,不然就无法判断 46 | 47 | 学习指令是相同的 48 | ?你好-你好啊 49 | 50 | 机器人会先使用普通用户数据比对库,后使用管理员数据比对库,并且是逐行比对,一旦找到答案,就会终止比对,并输出答案 51 | 52 | -------------------------------------------------------------------------------- /screenshot/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljkgpxs/QRobot/a966193a7d13f0de66f9c769aa5e335970141444/screenshot/screenshot.png -------------------------------------------------------------------------------- /start.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use 5.010; 4 | use Mojo::Webqq; 5 | use Mojo::Util qw(md5_sum); 6 | 7 | my @required_mojo_webqq_ver = ( '1', '7', '9' ); 8 | 9 | sub read_from_file 10 | { 11 | my $to_file = '/tmp/' . $_[0] . '.reply'; 12 | if(open(FILE, "<$to_file")) { 13 | my @content = ; 14 | close(FILE); 15 | @content; 16 | } 17 | else { 18 | return 0; 19 | } 20 | } 21 | 22 | sub passmsg 23 | { 24 | &read_from_file($_[0]); 25 | } 26 | 27 | #say "debug ".$qq."\n".$pwd; 28 | my $client = Mojo::Webqq->new( 29 | ua_debug => 0, 30 | # qq => $qq, 31 | login_type => "qrlogin", 32 | ); 33 | 34 | # 判断Mojo-Webqq版本是否达到要求 35 | my @version = split(/\./, $client->version); 36 | my $i = 0; 37 | while($version[$i] - $required_mojo_webqq_ver[$i] == 0) { 38 | $i++; 39 | if($i == 3) { 40 | last; 41 | } 42 | } 43 | if($i != 3 && $version[$i] - $required_mojo_webqq_ver[$i] < 0) { 44 | say "Your Mojo-Webqq version v$version[0].$version[1].$version[2] < v$required_mojo_webqq_ver[0].$required_mojo_webqq_ver[1].$required_mojo_webqq_ver[2], Please update your Mojo-Webqq and retry."; 45 | exit(1); 46 | } 47 | 48 | $client->on("input_qrcode"=>sub{ 49 | my ($client, $qrpath) = @_; 50 | # system('./tools/viewqr', $qrpath), 51 | $client->spawn( 52 | is_blocking => 1, 53 | cmd => sub{ system('./tools/viewqr', '-png', $qrpath) }, 54 | exec_timeout => 2, 55 | stdout_cb => sub { 56 | my($pid, $chunk) = @_; 57 | print $chunk; 58 | }, 59 | exit_cb => sub{}, 60 | ); 61 | }); 62 | 63 | # 开始登录 64 | $client->login(); 65 | $client->load("ShowMsg"); 66 | 67 | $client->on(receive_message=>sub{ 68 | my ($client,$msg) = @_; 69 | if($msg->type eq 'message') { 70 | $client->spawn( 71 | cmd => sub { system('./core/start.sh', $msg->type, $msg->sender->qq, $msg->content) }, 72 | exec_timeout => 5, 73 | exit_cb => sub{ 74 | my @reply_content = &passmsg($msg->sender->qq); 75 | if(@reply_content) { 76 | my $reply_text; 77 | foreach(@reply_content) { 78 | $reply_text .= $_; 79 | } 80 | $msg->reply($reply_text); 81 | } else { 82 | say "System message: No Reply"; 83 | } 84 | }, 85 | ); 86 | } 87 | # $client->reply_message($msg,$msg->{content}); 88 | }); 89 | 90 | $client->run; 91 | system("rm -f /tmp/*.reply >/dev/null 2>/dev/null"); 92 | 93 | -------------------------------------------------------------------------------- /tools/.gitignore: -------------------------------------------------------------------------------- 1 | /viewqr 2 | -------------------------------------------------------------------------------- /tools/LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /tools/Makefile: -------------------------------------------------------------------------------- 1 | DEBUG = 2 | all: 3 | @echo "**Building tools.viewqr" 4 | @gcc viewqr.c -o viewqr -lpng -ljpeg -O3 -Wall $(DEBUG) 5 | -------------------------------------------------------------------------------- /tools/README.md: -------------------------------------------------------------------------------- 1 | 用于在终端显示二维码 2 |
使用方法: 3 | 4 | ``` 5 | $ make 6 | $ ./viewqr [-jpg|-png] [ png filepath ] 7 | ``` 8 | ###截图: 9 | ![image](https://github.com/ljkgpxs/ViewQR/raw/master/screenshots/webqq_qr.png) 10 |
11 | ![image](https://github.com/ljkgpxs/ViewQR/raw/master/screenshots/screenshot1.png) 12 |
13 | ![image](https://github.com/ljkgpxs/ViewQR/raw/master/screenshots/weixin_qr.jpg) 14 |
15 | ![image](https://github.com/ljkgpxs/ViewQR/raw/master/screenshots/screenshot2.png) 16 | 17 | -------------------------------------------------------------------------------- /tools/screenshots/screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljkgpxs/QRobot/a966193a7d13f0de66f9c769aa5e335970141444/tools/screenshots/screenshot1.png -------------------------------------------------------------------------------- /tools/screenshots/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljkgpxs/QRobot/a966193a7d13f0de66f9c769aa5e335970141444/tools/screenshots/screenshot2.png -------------------------------------------------------------------------------- /tools/screenshots/webqq_qr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljkgpxs/QRobot/a966193a7d13f0de66f9c769aa5e335970141444/tools/screenshots/webqq_qr.png -------------------------------------------------------------------------------- /tools/screenshots/weixin_qr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljkgpxs/QRobot/a966193a7d13f0de66f9c769aa5e335970141444/tools/screenshots/weixin_qr.jpg -------------------------------------------------------------------------------- /tools/viewqr.c: -------------------------------------------------------------------------------- 1 | /* Project By ljk 2 | * http://ljkgpxs.xyz 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define DARK "\033[40;33m \033[0m" 13 | #define WHILTE "\033[47;37m \033[0m" 14 | #define PNG_BYTES_TO_CHECK 4 15 | #define ogr_x 7000 16 | #define ogr_y 7000 17 | 18 | unsigned char *tabr,*tabg,*tabb; 19 | unsigned char *tab2r,*tab2g,*tab2b; 20 | int image_x,image_y,depth,tempi, x, y; 21 | 22 | struct my_error_mgr { 23 | struct jpeg_error_mgr pub; 24 | jmp_buf setjmp_buffer; 25 | }; 26 | typedef struct my_error_mgr * my_error_ptr; 27 | 28 | int streq(const char *s1, const char *s2) { return strcmp(s1, s2) == 0; } 29 | 30 | 31 | int check_image(int ix,int iy,int id) 32 | { 33 | if ((ix>ogr_x) || (iy>ogr_y) || (id>32) || (ix<=0) || (iy<=0) || (id<=0)) { 34 | return 3; 35 | } 36 | ix++; 37 | iy++; 38 | if (ix*iy<256) ix=256; 39 | tabr=(unsigned char*)malloc(ix*iy); 40 | if (!tabr) fprintf(stderr,"Malloc error (tabr)\n"); 41 | tabg=(unsigned char*)malloc(ix*iy); 42 | if (!tabg) fprintf(stderr,"Malloc error (tabg)\n"); 43 | tabb=(unsigned char*)malloc(ix*iy); 44 | if (!tabb) fprintf(stderr,"Malloc error (tabb)\n"); 45 | tab2r=(unsigned char*)malloc(ix*iy); 46 | if (!tab2r) fprintf(stderr,"Malloc error (tab2r)\n"); 47 | tab2g=(unsigned char*)malloc(ix*iy); 48 | if (!tab2g) fprintf(stderr,"Malloc error (tab2g)\n"); 49 | tab2b=(unsigned char*)malloc(ix*iy); 50 | if (!tab2b) fprintf(stderr,"Malloc error (tab2b)\n"); 51 | 52 | return 0; 53 | } 54 | 55 | METHODDEF(void) my_error_exit(j_common_ptr cinfo) 56 | { 57 | my_error_ptr myerr = (my_error_ptr) cinfo->err; 58 | (*cinfo->err->output_message)(cinfo); 59 | longjmp(myerr->setjmp_buffer,1); 60 | } 61 | 62 | int read_jpg(char *file_name) 63 | { 64 | FILE *plik = fopen(file_name, "rb"); 65 | if(plik == NULL) 66 | return 0; 67 | short int JPsyg; 68 | struct jpeg_decompress_struct cinfo; 69 | struct my_error_mgr jerr; 70 | JSAMPARRAY buffer; 71 | int row_stride,jaka; 72 | 73 | if(!fread(&JPsyg, sizeof (short int), 1, plik)) 74 | return 0; 75 | if (JPsyg != -9985) { 76 | return 1; 77 | } 78 | rewind(plik); 79 | cinfo.err = jpeg_std_error(&jerr.pub); 80 | jerr.pub.error_exit = my_error_exit; 81 | 82 | if(setjmp(jerr.setjmp_buffer)) { 83 | jpeg_destroy_decompress(&cinfo); 84 | return 2; 85 | } 86 | 87 | 88 | jpeg_create_decompress(&cinfo); 89 | jpeg_stdio_src(&cinfo,plik); 90 | jpeg_read_header(&cinfo,TRUE); 91 | jpeg_start_decompress(&cinfo); 92 | 93 | image_x = cinfo.output_width; 94 | image_y = cinfo.output_height; 95 | jaka = cinfo.num_components; 96 | check_image(image_x, image_y, 8); 97 | 98 | row_stride = cinfo.output_width*cinfo.output_components; 99 | buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo,JPOOL_IMAGE, row_stride, 1); 100 | y = 0; 101 | while (cinfo.output_scanline < cinfo.output_height) { 102 | jpeg_read_scanlines(&cinfo, buffer, 1); 103 | if (jaka == 3) 104 | for(x=0; x < image_x; x++) 105 | { 106 | tabr[x+y*image_x] = buffer[0][x*3]; 107 | tabg[x+y*image_x] = buffer[0][x*3+1]; 108 | tabb[x+y*image_x] = buffer[0][x*3+2]; 109 | 110 | } 111 | else 112 | for(x = 0; x < image_x; x++) 113 | { 114 | tabr[x+y*image_x] = buffer[0][x]; 115 | tabg[x+y*image_x] = tabr[x+y*image_x]; 116 | tabb[x+y*image_x] = tabr[x+y*image_x]; 117 | 118 | } 119 | y++; 120 | } 121 | jpeg_finish_decompress(&cinfo); 122 | jpeg_destroy_decompress(&cinfo); 123 | rewind(plik); 124 | fseek(plik, 20, SEEK_CUR); 125 | tempi=fgetc(plik); 126 | if ((tempi == 255) && (fgetc(plik) == 254)) { 127 | fprintf(stderr,"Comment : "); 128 | tempi = fgetc(plik); 129 | tempi = fgetc(plik); 130 | for (x=0; x < tempi-2; x++) { 131 | printf("%c", fgetc(plik)); 132 | } 133 | printf("\n"); 134 | } 135 | return 1; 136 | } 137 | 138 | int read_png(char *file_name) 139 | { 140 | 141 | FILE *plik = fopen(file_name, "rb"); 142 | if(plik == NULL) 143 | return 0; 144 | png_bytep row_pointers[4000]; 145 | int row; 146 | unsigned char buf[PNG_BYTES_TO_CHECK]; 147 | png_structp png_ptr; 148 | png_infop info_ptr; 149 | png_uint_32 width, height; 150 | int bit_depth, color_type, interlace_type; 151 | 152 | if(!fread(buf, 1, PNG_BYTES_TO_CHECK,plik)) 153 | return 0; 154 | tempi = png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK); 155 | if (tempi != 0) 156 | return 1; 157 | rewind(plik); 158 | png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 159 | if(png_ptr == NULL) 160 | return 2; 161 | info_ptr = png_create_info_struct(png_ptr); 162 | if(info_ptr == NULL) { 163 | png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); 164 | return 2; 165 | } 166 | 167 | if(setjmp(png_jmpbuf(png_ptr))) { 168 | png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); 169 | return 2; 170 | } 171 | 172 | png_init_io(png_ptr, plik); 173 | png_read_info(png_ptr, info_ptr); 174 | png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); 175 | image_x = width; 176 | image_y = height; 177 | depth = bit_depth; 178 | tempi = png_get_channels(png_ptr, info_ptr); 179 | check_image(image_x, image_y, depth); 180 | 181 | if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 182 | png_set_gray_to_rgb(png_ptr); 183 | png_set_expand(png_ptr); 184 | png_read_update_info(png_ptr, info_ptr); 185 | tempi = png_get_channels(png_ptr, info_ptr); 186 | 187 | for (row = 0; row < height ; row++){ 188 | row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); 189 | } 190 | 191 | png_read_image(png_ptr, row_pointers); 192 | png_read_end(png_ptr, info_ptr); 193 | 194 | for (y = 0; y < image_y; y++) { 195 | for (x = 0; x < image_x; x++) 196 | { 197 | tabr[x+y*image_x] = row_pointers[y][x*tempi]; 198 | tabg[x+y*image_x] = row_pointers[y][x*tempi+1]; 199 | tabb[x+y*image_x] = row_pointers[y][x*tempi+2]; 200 | } 201 | } 202 | png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); 203 | fclose(plik); 204 | return 1; 205 | } 206 | 207 | int main(int argc, char **argv) 208 | { 209 | int res, unit_len = 0; 210 | unsigned char **ixy; 211 | if(argc <= 2) { 212 | printf("Usage: viewqr [-jpg|-png] [ File Path ]\n"); 213 | return 0; 214 | } 215 | 216 | // 读取图片数据 217 | argv++; 218 | if(streq(*argv, "-png")) { 219 | if(!(res = read_png(*(++argv)))) { 220 | fprintf(stderr, "Read png file failed(%d)\n", res); 221 | return 1; 222 | } 223 | unit_len = 5; 224 | } else if(streq(*argv, "-jpg")) { 225 | if(!(res = read_jpg(*(++argv)))) { 226 | fprintf(stderr, "Read jpg file failed(%d)\n", res); 227 | return 1; 228 | } 229 | unit_len = 7; 230 | } else { 231 | printf("Usage: viewqr [-jpg|-png] [ File Path ]\n"); 232 | return 0; 233 | } 234 | 235 | // 申请二维指针内存 236 | ixy = (unsigned char **)malloc(sizeof(unsigned char**)*image_y); 237 | for(tempi = 0; tempi < image_y; tempi++) { 238 | ixy[tempi] = (unsigned char *)malloc(sizeof(unsigned char *)*image_x); 239 | } 240 | 241 | // 转换R的原数据为坐标形式,并进行简单降噪 242 | for(tempi = 0, x = 0, y = 0; tempi < image_x * image_y; tempi++) { 243 | ixy[y][x++] = tabr[tempi]>100 ? 255:0; 244 | if((tempi + 1) % image_x == 0) { 245 | y++; 246 | x = 0; 247 | } 248 | } 249 | 250 | // 打印二维码 251 | if(unit_len == 5) 252 | printf("\n\n "); 253 | for(y = 0; y < image_y/unit_len; y++) { 254 | for(x = 0; x < image_x/unit_len; x++) 255 | if(ixy[y*unit_len][x*unit_len] == 255) 256 | printf(WHILTE); 257 | else 258 | printf(DARK); 259 | if(unit_len == 5) 260 | printf("\n "); 261 | else 262 | printf("\n"); 263 | } 264 | if(unit_len == 5) 265 | printf("\n\n"); 266 | 267 | // 释放内存 268 | for(tempi = 0; tempi < image_y; tempi++) { 269 | free(ixy[tempi]); 270 | } 271 | free(ixy); 272 | return 0; 273 | } 274 | 275 | -------------------------------------------------------------------------------- /version: -------------------------------------------------------------------------------- 1 | QRobot Project 2 | 3 | Version 2.5.1 4 | By Ljkgpxs 5 | --------------------------------------------------------------------------------