├── .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 | 
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 | 
10 |
11 | 
12 |
13 | 
14 |
15 | 
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 |
--------------------------------------------------------------------------------