├── .gitattributes ├── .github └── FUNDING.yml ├── .gitignore ├── BOIT DLL ├── AppLifeRoutine.c ├── BOIT DLL.vcxproj ├── BOIT DLL.vcxproj.filters ├── Base64.h ├── CQAPITransfer.c ├── CQAPITransfer.h ├── CQLog.c ├── CQP.lib ├── CoolQDef.h ├── CoolQ_API_Entry.c ├── CoolQ_State.h ├── DllMain.c ├── Global.h ├── SendEventHandler.c └── app.json ├── BOIT InfoStruct ├── BOIT InfoStruct.vcxitems └── BOIT InfoStruct.vcxitems.filters ├── BOIT Server ├── APITransfer.c ├── APITransfer.h ├── AsyncINet.c ├── AsyncINet.h ├── BOIT Server.vcxproj ├── BOIT Server.vcxproj.filters ├── Base64.c ├── CommandEvent.h ├── CommandManager.c ├── CommandManager.h ├── Command_about.c ├── Command_admin.c ├── Command_boast.c ├── Command_cat.c ├── Command_codeforces.c ├── Command_help.c ├── Command_luogu.c ├── Command_oier.c ├── Command_q_and_a.c ├── Command_qwq.c ├── Command_run.c ├── Command_run.h ├── Command_runcode.c ├── Command_savecode.c ├── Command_sponsor.c ├── Command_stop.c ├── Command_version.c ├── Corpus.c ├── Corpus.h ├── DirManagement.c ├── DirManagement.h ├── Global.h ├── HandleBOITCode.c ├── HandleBOITCode.h ├── InlineCommand.c ├── InlineCommand.h ├── MessageReply.c ├── MessageWatch.c ├── MessageWatch.h ├── PerCommandData.c ├── PerGroupData.c ├── PerUserData.c ├── Pic.cpp ├── Pic.h ├── RecvEventHandler.c ├── RecvEventHandler.h ├── RegisterRW.c ├── RegisterRW.h ├── RemoveCQEscapeChar.c ├── RemoveCQEscapeChar.h ├── SendEventDispatch.c ├── SendEventDispatch.h ├── ServerMain.c ├── ServerState.c ├── SessionManage.c ├── SessionManage.h ├── SimpleSandbox.c ├── SimpleSandbox.h ├── TokenManage.c ├── VBuffer.c ├── VBuffer.h └── WaitForConnThread.c ├── BOIT Shared ├── BOIT Shared.vcxitems ├── BOIT Shared.vcxitems.filters ├── BOITEventType.h ├── BOITInfoMaxDef.h ├── EstablishConn.c ├── EstablishConn.h ├── ObjectName.h └── SharedMemStruct.h ├── BOIT Version ├── BOIT Version.vcxitems ├── BOIT Version.vcxitems.filters ├── BOITVersion.h └── Settings.h ├── BOIT.sln ├── LICENSE ├── README.md ├── StringProcess ├── CommandProcess.c ├── CommandProcess.h ├── EncodeConvert.c ├── EncodeConvert.h ├── StringProcess.vcxitems ├── StringProcess.vcxitems.filters ├── URIEncode.c └── URIEncode.h └── cJSON ├── cJSON.c ├── cJSON.h └── cJSON.vcxitems /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | 13 | 14 | custom: https://afdian.net/@kernelbin 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | [Aa][Rr][Mm]/ 24 | [Aa][Rr][Mm]64/ 25 | bld/ 26 | [Bb]in/ 27 | [Oo]bj/ 28 | [Ll]og/ 29 | 30 | # Visual Studio 2015/2017 cache/options directory 31 | .vs/ 32 | # Uncomment if you have tasks that create the project's static files in wwwroot 33 | #wwwroot/ 34 | 35 | # Visual Studio 2017 auto generated files 36 | Generated\ Files/ 37 | 38 | # MSTest test Results 39 | [Tt]est[Rr]esult*/ 40 | [Bb]uild[Ll]og.* 41 | 42 | # NUNIT 43 | *.VisualState.xml 44 | TestResult.xml 45 | 46 | # Build Results of an ATL Project 47 | [Dd]ebugPS/ 48 | [Rr]eleasePS/ 49 | dlldata.c 50 | 51 | # Benchmark Results 52 | BenchmarkDotNet.Artifacts/ 53 | 54 | # .NET Core 55 | project.lock.json 56 | project.fragment.lock.json 57 | artifacts/ 58 | 59 | # StyleCop 60 | StyleCopReport.xml 61 | 62 | # Files built by Visual Studio 63 | *_i.c 64 | *_p.c 65 | *_h.h 66 | *.ilk 67 | *.meta 68 | *.obj 69 | *.iobj 70 | *.pch 71 | *.pdb 72 | *.ipdb 73 | *.pgc 74 | *.pgd 75 | *.rsp 76 | *.sbr 77 | *.tlb 78 | *.tli 79 | *.tlh 80 | *.tmp 81 | *.tmp_proj 82 | *_wpftmp.csproj 83 | *.log 84 | *.vspscc 85 | *.vssscc 86 | .builds 87 | *.pidb 88 | *.svclog 89 | *.scc 90 | 91 | # Chutzpah Test files 92 | _Chutzpah* 93 | 94 | # Visual C++ cache files 95 | ipch/ 96 | *.aps 97 | *.ncb 98 | *.opendb 99 | *.opensdf 100 | *.sdf 101 | *.cachefile 102 | *.VC.db 103 | *.VC.VC.opendb 104 | 105 | # Visual Studio profiler 106 | *.psess 107 | *.vsp 108 | *.vspx 109 | *.sap 110 | 111 | # Visual Studio Trace Files 112 | *.e2e 113 | 114 | # TFS 2012 Local Workspace 115 | $tf/ 116 | 117 | # Guidance Automation Toolkit 118 | *.gpState 119 | 120 | # ReSharper is a .NET coding add-in 121 | _ReSharper*/ 122 | *.[Rr]e[Ss]harper 123 | *.DotSettings.user 124 | 125 | # JustCode is a .NET coding add-in 126 | .JustCode 127 | 128 | # TeamCity is a build add-in 129 | _TeamCity* 130 | 131 | # DotCover is a Code Coverage Tool 132 | *.dotCover 133 | 134 | # AxoCover is a Code Coverage Tool 135 | .axoCover/* 136 | !.axoCover/settings.json 137 | 138 | # Visual Studio code coverage results 139 | *.coverage 140 | *.coveragexml 141 | 142 | # NCrunch 143 | _NCrunch_* 144 | .*crunch*.local.xml 145 | nCrunchTemp_* 146 | 147 | # MightyMoose 148 | *.mm.* 149 | AutoTest.Net/ 150 | 151 | # Web workbench (sass) 152 | .sass-cache/ 153 | 154 | # Installshield output folder 155 | [Ee]xpress/ 156 | 157 | # DocProject is a documentation generator add-in 158 | DocProject/buildhelp/ 159 | DocProject/Help/*.HxT 160 | DocProject/Help/*.HxC 161 | DocProject/Help/*.hhc 162 | DocProject/Help/*.hhk 163 | DocProject/Help/*.hhp 164 | DocProject/Help/Html2 165 | DocProject/Help/html 166 | 167 | # Click-Once directory 168 | publish/ 169 | 170 | # Publish Web Output 171 | *.[Pp]ublish.xml 172 | *.azurePubxml 173 | # Note: Comment the next line if you want to checkin your web deploy settings, 174 | # but database connection strings (with potential passwords) will be unencrypted 175 | *.pubxml 176 | *.publishproj 177 | 178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 179 | # checkin your Azure Web App publish settings, but sensitive information contained 180 | # in these scripts will be unencrypted 181 | PublishScripts/ 182 | 183 | # NuGet Packages 184 | *.nupkg 185 | # The packages folder can be ignored because of Package Restore 186 | **/[Pp]ackages/* 187 | # except build/, which is used as an MSBuild target. 188 | !**/[Pp]ackages/build/ 189 | # Uncomment if necessary however generally it will be regenerated when needed 190 | #!**/[Pp]ackages/repositories.config 191 | # NuGet v3's project.json files produces more ignorable files 192 | *.nuget.props 193 | *.nuget.targets 194 | 195 | # Microsoft Azure Build Output 196 | csx/ 197 | *.build.csdef 198 | 199 | # Microsoft Azure Emulator 200 | ecf/ 201 | rcf/ 202 | 203 | # Windows Store app package directories and files 204 | AppPackages/ 205 | BundleArtifacts/ 206 | Package.StoreAssociation.xml 207 | _pkginfo.txt 208 | *.appx 209 | 210 | # Visual Studio cache files 211 | # files ending in .cache can be ignored 212 | *.[Cc]ache 213 | # but keep track of directories ending in .cache 214 | !?*.[Cc]ache/ 215 | 216 | # Others 217 | ClientBin/ 218 | ~$* 219 | *~ 220 | *.dbmdl 221 | *.dbproj.schemaview 222 | *.jfm 223 | *.pfx 224 | *.publishsettings 225 | orleans.codegen.cs 226 | 227 | # Including strong name files can present a security risk 228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 229 | #*.snk 230 | 231 | # Since there are multiple workflows, uncomment next line to ignore bower_components 232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 233 | #bower_components/ 234 | 235 | # RIA/Silverlight projects 236 | Generated_Code/ 237 | 238 | # Backup & report files from converting an old project file 239 | # to a newer Visual Studio version. Backup files are not needed, 240 | # because we have git ;-) 241 | _UpgradeReport_Files/ 242 | Backup*/ 243 | UpgradeLog*.XML 244 | UpgradeLog*.htm 245 | ServiceFabricBackup/ 246 | *.rptproj.bak 247 | 248 | # SQL Server files 249 | *.mdf 250 | *.ldf 251 | *.ndf 252 | 253 | # Business Intelligence projects 254 | *.rdl.data 255 | *.bim.layout 256 | *.bim_*.settings 257 | *.rptproj.rsuser 258 | *- Backup*.rdl 259 | 260 | # Microsoft Fakes 261 | FakesAssemblies/ 262 | 263 | # GhostDoc plugin setting file 264 | *.GhostDoc.xml 265 | 266 | # Node.js Tools for Visual Studio 267 | .ntvs_analysis.dat 268 | node_modules/ 269 | 270 | # Visual Studio 6 build log 271 | *.plg 272 | 273 | # Visual Studio 6 workspace options file 274 | *.opt 275 | 276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 277 | *.vbw 278 | 279 | # Visual Studio LightSwitch build output 280 | **/*.HTMLClient/GeneratedArtifacts 281 | **/*.DesktopClient/GeneratedArtifacts 282 | **/*.DesktopClient/ModelManifest.xml 283 | **/*.Server/GeneratedArtifacts 284 | **/*.Server/ModelManifest.xml 285 | _Pvt_Extensions 286 | 287 | # Paket dependency manager 288 | .paket/paket.exe 289 | paket-files/ 290 | 291 | # FAKE - F# Make 292 | .fake/ 293 | 294 | # JetBrains Rider 295 | .idea/ 296 | *.sln.iml 297 | 298 | # CodeRush personal settings 299 | .cr/personal 300 | 301 | # Python Tools for Visual Studio (PTVS) 302 | __pycache__/ 303 | *.pyc 304 | 305 | # Cake - Uncomment if you are using it 306 | # tools/** 307 | # !tools/packages.config 308 | 309 | # Tabs Studio 310 | *.tss 311 | 312 | # Telerik's JustMock configuration file 313 | *.jmconfig 314 | 315 | # BizTalk build output 316 | *.btp.cs 317 | *.btm.cs 318 | *.odx.cs 319 | *.xsd.cs 320 | 321 | # OpenCover UI analysis results 322 | OpenCover/ 323 | 324 | # Azure Stream Analytics local run output 325 | ASALocalRun/ 326 | 327 | # MSBuild Binary and Structured Log 328 | *.binlog 329 | 330 | # NVidia Nsight GPU debugger configuration file 331 | *.nvuser 332 | 333 | # MFractors (Xamarin productivity tool) working folder 334 | .mfractor/ 335 | 336 | # Local History for Visual Studio 337 | .localhistory/ 338 | 339 | # BeatPulse healthcheck temp database 340 | healthchecksdb -------------------------------------------------------------------------------- /BOIT DLL/AppLifeRoutine.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include"Global.h" 3 | #include"CQAPITransfer.h" 4 | #include"EstablishConn.h" 5 | #include"BOITEventType.h" 6 | #include 7 | #include"EncodeConvert.h" 8 | 9 | //生命周期 10 | 11 | int AppInitialize()//初始化时会被执行 12 | { 13 | //InitializeEventDispatch(); 14 | InitializeSRWLock(&RecvLock); 15 | 16 | _beginthreadex(0, 0, WaitForConnThread, 0, 0, 0); 17 | return 0; 18 | } 19 | 20 | int AppFinialize()//结束时会被执行 21 | { 22 | CleanConn(); 23 | return 0; 24 | } 25 | 26 | int AppEnabled()//启用时执行(如果初始化时是启用的,会在AppInitialize后执行一次) 27 | { 28 | return 0; 29 | } 30 | 31 | int AppDisabled()//禁用时执行(如果结束时是启用的,会在AppFinialize前执行一次,这点和cq原生函数不一样) 32 | { 33 | return 0; 34 | } 35 | 36 | 37 | 38 | int HandlePrivateMessage(int subType, int msgId, long long fromQQ, const char* msg, int font) 39 | { 40 | if (GetConnState() == 0) 41 | { 42 | AddLog(CQLOG_INFO, "BOIT", "和Server之间的连接已经断开,消息未处理"); 43 | return 0; 44 | } 45 | AcquireSRWLockExclusive(&RecvLock); 46 | 47 | __try 48 | { 49 | pSharedMemRecv->EventType = BOIT_EVENT_RECV_PRIVATE; 50 | pSharedMemRecv->u.PrivateMsg.SubType = subType; 51 | 52 | int cchWideCharLen = MultiByteToWideChar(CP_GB18030, 0, msg, -1, 0, 0); 53 | cchWideCharLen = min(cchWideCharLen, BOIT_MAX_TEXTLEN); 54 | MultiByteToWideChar(CP_GB18030, 0, msg, -1, pSharedMemRecv->u.PrivateMsg.Msg, cchWideCharLen); 55 | pSharedMemRecv->u.PrivateMsg.Msg[cchWideCharLen] = 0; 56 | pSharedMemRecv->u.PrivateMsg.Msg[cchWideCharLen + 1] = 0; 57 | 58 | pSharedMemRecv->u.PrivateMsg.QQID = fromQQ; 59 | 60 | SetEvent(hEventRecvStart);//等待对方读取 61 | 62 | if (ConnWaitForObject(hEventRecvEnd) == 0) 63 | { 64 | __leave; 65 | } 66 | 67 | //这里应有返回值处理。但是好像没啥好处理的。那就直接通知对方读取好了8 68 | SetEvent(hEventRecvRet); 69 | 70 | //成功 71 | } 72 | __finally 73 | { 74 | ReleaseSRWLockExclusive(&RecvLock); 75 | } 76 | 77 | 78 | return 0; 79 | } 80 | 81 | 82 | int HandleGroupMessage(int subType, int msgId, long long fromGroup, long long fromQQ, const char * fromAnonymous, const char * msg, int font) 83 | { 84 | if (GetConnState() == 0) 85 | { 86 | AddLog(CQLOG_INFO, "BOIT", "和Server之间的连接已经断开,消息未处理"); 87 | return 0; 88 | } 89 | AcquireSRWLockExclusive(&RecvLock); 90 | 91 | __try 92 | { 93 | pSharedMemRecv->EventType = BOIT_EVENT_RECV_GROUP; 94 | pSharedMemRecv->u.GroupMsg.SubType = subType; 95 | int cchWideCharLen = MultiByteToWideChar(CP_GB18030, 0, msg, -1, 0, 0); 96 | cchWideCharLen = min(cchWideCharLen, BOIT_MAX_TEXTLEN); 97 | MultiByteToWideChar(CP_GB18030, 0, msg, -1, pSharedMemRecv->u.GroupMsg.Msg, cchWideCharLen); 98 | pSharedMemRecv->u.GroupMsg.Msg[cchWideCharLen] = 0; 99 | pSharedMemRecv->u.GroupMsg.Msg[cchWideCharLen + 1] = 0; 100 | 101 | cchWideCharLen = min(cchWideCharLen, BOIT_MAX_NICKLEN); 102 | MultiByteToWideChar(CP_GB18030, 0, fromAnonymous, -1, pSharedMemRecv->u.GroupMsg.AnonymousName, cchWideCharLen); 103 | pSharedMemRecv->u.GroupMsg.AnonymousName[cchWideCharLen] = 0; 104 | pSharedMemRecv->u.GroupMsg.AnonymousName[cchWideCharLen + 1] = 0; 105 | 106 | 107 | pSharedMemRecv->u.GroupMsg.QQID = fromQQ; 108 | pSharedMemRecv->u.GroupMsg.GroupID = fromGroup; 109 | 110 | SetEvent(hEventRecvStart);//等待对方读取 111 | 112 | if (ConnWaitForObject(hEventRecvEnd) == 0) 113 | { 114 | __leave; 115 | } 116 | 117 | //这里应有返回值处理。但是好像没啥好处理的。那就直接通知对方读取好了8 118 | SetEvent(hEventRecvRet); 119 | 120 | //成功 121 | } 122 | __finally 123 | { 124 | ReleaseSRWLockExclusive(&RecvLock); 125 | } 126 | 127 | return 0; 128 | } 129 | -------------------------------------------------------------------------------- /BOIT DLL/BOIT DLL.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {CCE394D1-964D-4B5F-BEB2-7BB1F016B268} 24 | Win32Proj 25 | BOITDLL 26 | 10.0.18362.0 27 | 28 | 29 | 30 | DynamicLibrary 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | DynamicLibrary 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | DynamicLibrary 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | true 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | false 87 | 88 | 89 | 90 | Level3 91 | true 92 | WIN32;_DEBUG;BOITDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 93 | true 94 | 95 | 96 | Windows 97 | true 98 | false 99 | 100 | 101 | 102 | 103 | Level3 104 | true 105 | _DEBUG;BOITDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 106 | true 107 | 108 | 109 | Windows 110 | true 111 | false 112 | 113 | 114 | 115 | 116 | Level3 117 | true 118 | true 119 | true 120 | WIN32;NDEBUG;BOITDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 121 | true 122 | MultiThreaded 123 | 124 | 125 | Windows 126 | true 127 | true 128 | true 129 | false 130 | 131 | 132 | 133 | 134 | Level3 135 | true 136 | true 137 | true 138 | NDEBUG;BOITDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 139 | true 140 | 141 | 142 | Windows 143 | true 144 | true 145 | true 146 | false 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /BOIT DLL/BOIT DLL.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {b0e9c004-b23e-4e33-b8f5-145fed7a9f9e} 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 | CoolQ Lib 49 | 50 | 51 | 52 | 53 | CoolQ Lib 54 | 55 | 56 | 57 | 58 | 头文件 59 | 60 | 61 | 头文件 62 | 63 | 64 | 头文件 65 | 66 | 67 | 头文件 68 | 69 | 70 | 头文件 71 | 72 | 73 | -------------------------------------------------------------------------------- /BOIT DLL/Base64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | int Base64Encode(const unsigned char* sourcedata, char* base64); 4 | int Base64Decode(const char* base64, unsigned char* bindata); -------------------------------------------------------------------------------- /BOIT DLL/CQAPITransfer.c: -------------------------------------------------------------------------------- 1 | #define WIN32_LEAN_AND_MEAN 2 | #include 3 | #include"CoolQDef.h" 4 | #include"CoolQ_State.h" 5 | #include "CQAPITransfer.h" 6 | 7 | int SendPrivateMessage(long long QQID, const char* msg) 8 | { 9 | return CQ_sendPrivateMsg(CQAuthCode, QQID, msg); 10 | } 11 | 12 | 13 | int SendGroupMessage(long long GroupID, const char* msg) 14 | { 15 | return CQ_sendGroupMsg(CQAuthCode, GroupID, msg); 16 | } 17 | 18 | 19 | const char * GetGroupMemberInfo(long long GroupID, long long QQID, BOOL NoCache) 20 | { 21 | return CQ_getGroupMemberInfoV2(CQAuthCode, GroupID, QQID, NoCache); 22 | } 23 | 24 | 25 | const char* GetStrangerInfo(long long QQID, BOOL NoCache) 26 | { 27 | return CQ_getStrangerInfo(CQAuthCode, QQID, NoCache); 28 | } 29 | 30 | const char* GetAppDirectory() 31 | { 32 | return CQ_getAppDirectory(CQAuthCode); 33 | } -------------------------------------------------------------------------------- /BOIT DLL/CQAPITransfer.h: -------------------------------------------------------------------------------- 1 | #define WIN32_LEAN_AND_MEAN 2 | #include 3 | #include"CoolQDef.h" 4 | #include"CoolQ_State.h" 5 | 6 | int SendPrivateMessage(long long QQID, const char* msg); 7 | 8 | int SendGroupMessage(long long GroupID, const char* msg); 9 | 10 | const char* GetGroupMemberInfo(long long GroupID, long long QQID, BOOL NoCache); 11 | 12 | const char* GetStrangerInfo(long long QQID, BOOL NoCache); 13 | 14 | const char* GetAppDirectory(); -------------------------------------------------------------------------------- /BOIT DLL/CQLog.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT DLL/CQLog.c -------------------------------------------------------------------------------- /BOIT DLL/CQP.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT DLL/CQP.lib -------------------------------------------------------------------------------- /BOIT DLL/CoolQDef.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT DLL/CoolQDef.h -------------------------------------------------------------------------------- /BOIT DLL/CoolQ_API_Entry.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT DLL/CoolQ_API_Entry.c -------------------------------------------------------------------------------- /BOIT DLL/CoolQ_State.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int CQAuthCode; 4 | int CQEnabled; -------------------------------------------------------------------------------- /BOIT DLL/DllMain.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT DLL/DllMain.c -------------------------------------------------------------------------------- /BOIT DLL/Global.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT DLL/Global.h -------------------------------------------------------------------------------- /BOIT DLL/SendEventHandler.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT DLL/SendEventHandler.c -------------------------------------------------------------------------------- /BOIT DLL/app.json: -------------------------------------------------------------------------------- 1 | // 酷Q 的Json文件支持以 // 开头的注释。 2 | // 开发模式下,应用的 app.dll 及 app.json 文件须放在 dev/[appid]/ 目录下,应用 AppInfo 函数返回的内容须改为 appid 3 | // 如 appid=com.example.demo, 则dll及json文件需分别放在 dev/com.example.demo/app.dll、dev/com.example.demo/app.json 4 | // [重要] appid 规则见 https://cqp.im/v9/appid 5 | { 6 | "ret":1, // 返回码,固定为1 7 | "apiver":9, // Api版本,本SDK为9 8 | "name":"BOIT", // 应用名称 9 | "version":"2.0.0 Beta", // 应用版本 10 | "version_id":2, // 应用顺序版本(每次发布时至少+1) 11 | "author":"kernel.bin", // 应用作者 12 | "description":"BOT for OIers. /*BOIT = BOT + OI; yh蒟蒻写的给OIers用的一个bot,OI Bot的第二版。*/", 13 | "event":[ // 事件列表,同一事件类型可重复定义(发布前请删除无用事件) 14 | { 15 | "id":1, // 事件ID 16 | "type":21, // 事件类型 17 | "name":"私聊消息处理", // 事件名称 18 | "function":"_eventPrivateMsg", // 事件对应函数 19 | "priority":30000 // 事件优先级(参见 https://cqp.im/deveventpriority ) 20 | }, 21 | { 22 | "id":2, 23 | "type":2, 24 | "name":"群消息处理", 25 | "function":"_eventGroupMsg", 26 | "priority":30000 27 | }, 28 | //{ 29 | // "id":3, 30 | // "type":4, 31 | // "name":"讨论组消息处理", 32 | // "function":"_eventDiscussMsg", 33 | // "priority":30000 34 | //}, 35 | //{ 36 | // "id":4, 37 | // "type":11, 38 | // "name":"群文件上传事件处理", 39 | // "function":"_eventGroupUpload", 40 | // "priority":30000 41 | //}, 42 | //{ 43 | // "id":5, 44 | // "type":101, 45 | // "name":"群管理变动事件处理", 46 | // "function":"_eventSystem_GroupAdmin", 47 | // "priority":30000 48 | //}, 49 | //{ 50 | // "id":6, 51 | // "type":102, 52 | // "name":"群成员减少事件处理", 53 | // "function":"_eventSystem_GroupMemberDecrease", 54 | // "priority":30000 55 | //}, 56 | //{ 57 | // "id":7, 58 | // "type":103, 59 | // "name":"群成员增加事件处理", 60 | // "function":"_eventSystem_GroupMemberIncrease", 61 | // "priority":30000 62 | //}, 63 | //{ 64 | // "id":8, 65 | // "type":104, 66 | // "name":"群禁言事件处理", 67 | // "function":"_eventSystem_GroupBan", 68 | // "priority":30000 69 | //}, 70 | //{ 71 | // "id":10, 72 | // "type":201, 73 | // "name":"好友已添加事件处理", 74 | // "function":"_eventFriend_Add", 75 | // "priority":30000 76 | //}, 77 | //{ 78 | // "id":11, 79 | // "type":301, 80 | // "name":"好友添加请求处理", 81 | // "function":"_eventRequest_AddFriend", 82 | // "priority":30000 83 | //}, 84 | //{ 85 | // "id":12, 86 | // "type":302, 87 | // "name":"群添加请求处理", 88 | // "function":"_eventRequest_AddGroup", 89 | // "priority":30000 90 | //}, 91 | { 92 | "id":1001, 93 | "type":1001, 94 | "name":"酷Q启动事件", 95 | "priority":30000, 96 | "function":"_eventStartup" 97 | }, 98 | { 99 | "id":1002, 100 | "type":1002, 101 | "name":"酷Q关闭事件", 102 | "priority":30000, 103 | "function":"_eventExit" 104 | }, 105 | { 106 | "id":1003, 107 | "type":1003, 108 | "name":"应用已被启用", 109 | "priority":30000, 110 | "function":"_eventEnable" 111 | }, 112 | { 113 | "id":1004, 114 | "type":1004, 115 | "name":"应用将被停用", 116 | "priority":30000, 117 | "function":"_eventDisable" 118 | } 119 | ], 120 | //"menu":[ // 设置菜单(发布前请删除无用菜单,如果无需设置菜单请全部删除) 121 | // { 122 | // "name":"设置A", //菜单名称 123 | // "function":"_menuA" //菜单对应函数 124 | // }, 125 | // { 126 | // "name":"设置B", 127 | // "function":"_menuB" 128 | // } 129 | //], 130 | "status":[ // 悬浮窗状态(见 com.example.status 样例) 131 | 132 | ], 133 | "auth":[ // 应用权限(发布前请删除无用权限) 134 | //20, //[敏感]取Cookies getCookies / getCsrfToken 135 | //30, //接收语音 getRecord 136 | 101, //发送群消息 sendGroupMsg 137 | 103, //发送讨论组消息 sendDiscussMsg 138 | 106, //发送私聊消息 sendPrivateMsg 139 | //110, //[敏感]发送赞 sendLike 140 | //120, //置群员移除 setGroupKick 141 | //121, //置群员禁言 setGroupBan 142 | //122, //置群管理员 setGroupAdmin 143 | //123, //置全群禁言 setGroupWholeBan 144 | //124, //置匿名群员禁言 setGroupAnonymousBan 145 | //125, //置群匿名设置 setGroupAnonymous 146 | //126, //置群成员名片 setGroupCard 147 | //127, //[敏感]置群退出 setGroupLeave 148 | //128, //置群成员专属头衔 setGroupSpecialTitle 149 | 130, //取群成员信息 getGroupMemberInfo 150 | 131, //取陌生人信息 getStrangerInfo 151 | 132, //取群信息 getGroupInfo 152 | //140, //置讨论组退出 setDiscussLeave 153 | //150, //置好友添加请求 setFriendAddRequest 154 | //151, //置群添加请求 setGroupAddRequest 155 | //160, //取群成员列表 getGroupMemberList 156 | 161, //取群列表 getGroupList 157 | 162, //取好友列表 getFriendList 158 | 180 //撤回消息 deleteMsg 159 | ] 160 | } -------------------------------------------------------------------------------- /BOIT InfoStruct/BOIT InfoStruct.vcxitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | {78c15114-d8db-40c2-be51-a255768320a6} 7 | 8 | 9 | 10 | %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /BOIT InfoStruct/BOIT InfoStruct.vcxitems.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /BOIT Server/APITransfer.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/APITransfer.c -------------------------------------------------------------------------------- /BOIT Server/APITransfer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include"SessionManage.h" 4 | #include"SharedMemStruct.h" 5 | 6 | 7 | int SendPrivateMessage(long long QQID, WCHAR* Msg); 8 | int RecvPrivateMessage(long long QQID, int SubType, WCHAR* Msg); 9 | 10 | int SendGroupMessage(long long GroupID, WCHAR* Msg); 11 | int RecvGroupMessage(long long GroupID, long long QQID, int SubType, WCHAR* AnonymousName, WCHAR* Msg); 12 | 13 | int RetrieveGroupMemberInfo(pBOIT_SESSION boitSession, BOOL NoCache, pBOIT_GROUPMEMBER_INFO GroupMemberInfo); 14 | int RetrieveStrangerInfo(pBOIT_SESSION boitSession, BOOL NoCache, pBOIT_STRANGER_INFO StrangerInfo); 15 | 16 | int SendBackMessage(pBOIT_SESSION boitSession, WCHAR* Msg); 17 | 18 | 19 | -------------------------------------------------------------------------------- /BOIT Server/AsyncINet.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/AsyncINet.c -------------------------------------------------------------------------------- /BOIT Server/AsyncINet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include"VBuffer.h" 6 | 7 | 8 | 9 | #define ASYNCINET_REASON_SUCCESS 1 10 | #define ASYNCINET_REASON_FAILED 2 11 | 12 | 13 | typedef 14 | int 15 | (*ASYNC_INET_CALLBACK)( 16 | UINT iReason, 17 | pVBUF ReceivedBuf, 18 | PBYTE ExtData 19 | ); 20 | 21 | 22 | #define ASYNC_INET_BUF 4096 23 | 24 | typedef struct __tagAsyncINet 25 | { 26 | HINTERNET hInet; 27 | HINTERNET hConnect; 28 | }ASYNCINET_INFO, * pASYNCINET_INFO; 29 | 30 | typedef struct __tagAsyncRequest 31 | { 32 | BYTE ReadBuffer[ASYNC_INET_BUF]; 33 | DWORD BytesRead; 34 | 35 | HINTERNET hRequest; 36 | pVBUF vBuffer; 37 | BOOL bRequestComplete; 38 | 39 | PBYTE ExtData; 40 | 41 | ASYNC_INET_CALLBACK AsyncCallback; 42 | }ASYNC_REQUEST, * pASYNC_REQUEST; 43 | 44 | 45 | 46 | pASYNCINET_INFO AsyncINetInit(WCHAR* ServerURL); 47 | 48 | BOOL AsyncINetCleanup(pASYNCINET_INFO AsyncINetInfo); 49 | 50 | BOOL AsyncRequestGet(pASYNCINET_INFO AsyncINetInfo, WCHAR* Url, PBYTE ExtData, ASYNC_INET_CALLBACK AsyncCallback); 51 | 52 | -------------------------------------------------------------------------------- /BOIT Server/BOIT Server.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {E971129E-1CA0-4C70-8208-304B32243F91} 24 | BOITServer 25 | 10.0.18362.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v142 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v142 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v142 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v142 51 | true 52 | Unicode 53 | false 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | true 79 | 80 | 81 | true 82 | 83 | 84 | false 85 | 86 | 87 | false 88 | 89 | 90 | 91 | Level3 92 | true 93 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 94 | true 95 | 96 | 97 | Console 98 | true 99 | 100 | 101 | 102 | 103 | Level3 104 | true 105 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 106 | true 107 | 108 | 109 | Console 110 | true 111 | 112 | 113 | 114 | 115 | Level3 116 | true 117 | true 118 | true 119 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 120 | true 121 | MultiThreaded 122 | 123 | 124 | Console 125 | true 126 | true 127 | true 128 | 129 | 130 | 131 | 132 | Level3 133 | true 134 | true 135 | true 136 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 137 | true 138 | true 139 | MultiThreaded 140 | Speed 141 | 142 | 143 | Console 144 | true 145 | true 146 | true 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /BOIT Server/BOIT Server.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {da60ae88-3130-42bc-a589-3826265be5e1} 18 | 19 | 20 | {1f248004-4a0b-43d8-b5c3-ab38094bb7b1} 21 | 22 | 23 | {d190c16f-d790-4b79-976a-80726a39b55c} 24 | 25 | 26 | {a9c26bb1-3e00-417a-adc7-676fcf1a186c} 27 | 28 | 29 | {ded49be2-846d-4be3-ba08-a94d6bda6011} 30 | 31 | 32 | {8a66d1aa-7201-4fc9-9e61-b2301e2a7228} 33 | 34 | 35 | {afff87d3-5f3e-4260-bd01-62c93a098689} 36 | 37 | 38 | {216af931-71c2-403b-abf6-5b9c804abc5d} 39 | 40 | 41 | {1beaf9fd-6bd3-48e6-acf1-5f318f7669ff} 42 | 43 | 44 | {3ebaaac6-e701-4feb-9dab-8962572d6101} 45 | 46 | 47 | {2f777593-e2ae-4aa0-890c-b1a82ab81f02} 48 | 49 | 50 | {9ed838b4-78d2-449d-947d-70a22b00351b} 51 | 52 | 53 | {5e5ea7e6-8931-4697-ba78-d92c6e02c465} 54 | 55 | 56 | {b2ebdbaa-b141-4f4b-bc67-b70ab188d006} 57 | 58 | 59 | {c874d52d-244f-45d9-bbee-f2b61934a892} 60 | 61 | 62 | {da5508af-109d-4ecc-940b-296bfb3abac4} 63 | 64 | 65 | {f5c5e421-78b7-4f3d-a2a2-e6877ac63daa} 66 | 67 | 68 | {f7420c86-4e6f-4124-b9b9-e6ff6a7f8541} 69 | 70 | 71 | {7c7c0bb6-fe90-40c8-8680-b9a3b21e623e} 72 | 73 | 74 | {45930e49-1d64-402e-89cc-c1c26d8b3cc9} 75 | 76 | 77 | {aef568cc-8fd3-4452-80cc-4c661b0efb8d} 78 | 79 | 80 | {2afa450a-9ff2-455a-81f6-7a48a807963f} 81 | 82 | 83 | {abf01ef4-d057-40f8-b22a-71e554fbb242} 84 | 85 | 86 | {6077c956-fa43-41e5-9f76-21cabdd5a24d} 87 | 88 | 89 | {db5e04c9-90cf-4244-863e-17b209461514} 90 | 91 | 92 | {42086f9b-6ce7-4fa6-bd1a-ee4317a8b75f} 93 | 94 | 95 | {7a11dbcd-e4c2-4baa-a1a3-3e7055c0f861} 96 | 97 | 98 | {05f711d7-19b8-4a22-9e7d-54486fe7a4a9} 99 | 100 | 101 | {e17d422f-60ea-480f-80b1-6485ce9ade16} 102 | 103 | 104 | {a910fb7a-664d-4868-a854-8f155f0197b2} 105 | 106 | 107 | {92c2e432-2c2c-4141-b1cd-95a10e661ae6} 108 | 109 | 110 | {da54d1dc-da21-4d5f-9341-7be33e2e514b} 111 | 112 | 113 | {b0e802f9-8b38-42e3-b07e-ac6dac3b7d48} 114 | 115 | 116 | {f55079db-7fb3-442a-9988-bbb2f1bf37f9} 117 | 118 | 119 | {924ff8f0-2e3c-4436-8dc0-699379eab0bb} 120 | 121 | 122 | {75dbdbb1-2a53-446d-92b3-5040d696a55b} 123 | 124 | 125 | {dac781c0-6a22-4ace-9f68-6ed0d353d23e} 126 | 127 | 128 | {32a30a85-1b8d-4d5c-b123-e39d77d1ddc1} 129 | 130 | 131 | {9d456a87-ec25-4155-aebb-576782a18b35} 132 | 133 | 134 | {ea92ccfa-02ab-4f03-b5aa-abaa9e12e172} 135 | 136 | 137 | {1ceb090b-70a3-46db-9355-bdebf16b681a} 138 | 139 | 140 | {68aaadfa-1afe-485a-ac4d-10b6f6a850dd} 141 | 142 | 143 | {258ffeba-170c-4383-97d8-b6a153f26c65} 144 | 145 | 146 | {bbe3c8ed-a85d-4300-9204-eddff7a589e8} 147 | 148 | 149 | {0b23ddb9-607c-4865-a3f8-4e0fb4bd31ff} 150 | 151 | 152 | {4f1213a0-1b45-4f59-8ce9-39b7d8309fa6} 153 | 154 | 155 | {294b99b7-9b78-48ce-b4c5-379a4fda5265} 156 | 157 | 158 | {20060292-656f-4184-9ca6-869118cebab8} 159 | 160 | 161 | {a94ea5e6-966d-4db2-b15f-c46c17834712} 162 | 163 | 164 | {592cbf17-2490-4651-b5b9-b04cb52900fa} 165 | 166 | 167 | {86c10e14-8de8-499c-b916-158c18c80bb9} 168 | 169 | 170 | 171 | 172 | 源文件\底层事件处理器 173 | 174 | 175 | 源文件\底层事件处理器 176 | 177 | 178 | 源文件\入口函数 179 | 180 | 181 | 源文件\服务状态 182 | 183 | 184 | 源文件\API转发中间层 185 | 186 | 187 | 源文件\注册表读写 188 | 189 | 190 | 源文件\目录管理 191 | 192 | 193 | 源文件\指令处理 194 | 195 | 196 | 源文件\指令回调 197 | 198 | 199 | 源文件\指令回调\qwq 200 | 201 | 202 | 源文件\指令回调\about 203 | 204 | 205 | 源文件\指令回调\help 206 | 207 | 208 | 源文件\目录管理\用户目录管理 209 | 210 | 211 | 源文件\指令回调\run 212 | 213 | 214 | 源文件\目录管理\指令目录管理 215 | 216 | 217 | 源文件\简易沙盒 218 | 219 | 220 | 源文件\会话管理 221 | 222 | 223 | 源文件\指令回调\stop 224 | 225 | 226 | 源文件\VBuffer 227 | 228 | 229 | 源文件\CQ码转义 230 | 231 | 232 | 源文件\指令回调\q&a 233 | 234 | 235 | 源文件\指令回调\猫猫 236 | 237 | 238 | 源文件\目录管理\群目录管理 239 | 240 | 241 | 源文件\目录管理 242 | 243 | 244 | 源文件\指令回调\run 245 | 246 | 247 | 源文件\指令回调\run 248 | 249 | 250 | 源文件\BOIT码转义 251 | 252 | 253 | 源文件\消息监视 254 | 255 | 256 | 源文件\指令回调\boast 257 | 258 | 259 | 源文件\指令回调\version 260 | 261 | 262 | 源文件\指令回调\oier 263 | 264 | 265 | 源文件\语料库 266 | 267 | 268 | 源文件\指令回调\codeforces 269 | 270 | 271 | 源文件\异步网络 272 | 273 | 274 | 源文件\图片处理 275 | 276 | 277 | 源文件\消息回复 278 | 279 | 280 | 源文件\指令回调\打钱 281 | 282 | 283 | 源文件\指令回调\luogu 284 | 285 | 286 | 源文件\指令回调\admin 287 | 288 | 289 | 290 | 291 | 头文件 292 | 293 | 294 | 头文件\底层事件处理器 295 | 296 | 297 | 头文件\底层事件处理器 298 | 299 | 300 | 头文件\API转发中间层 301 | 302 | 303 | 头文件\目录管理 304 | 305 | 306 | 头文件\注册表读写 307 | 308 | 309 | 头文件\指令处理 310 | 311 | 312 | 头文件\指令回调 313 | 314 | 315 | 头文件\指令回调 316 | 317 | 318 | 头文件\会话管理 319 | 320 | 321 | 头文件\简易沙盒 322 | 323 | 324 | 头文件\VBuffer 325 | 326 | 327 | 头文件\CQ码转义 328 | 329 | 330 | 头文件\BOIT码转义 331 | 332 | 333 | 头文件\消息监视 334 | 335 | 336 | 头文件\语料库 337 | 338 | 339 | 头文件\指令回调\run相关指令 340 | 341 | 342 | 头文件\异步网络 343 | 344 | 345 | 头文件\图片处理 346 | 347 | 348 | -------------------------------------------------------------------------------- /BOIT Server/Base64.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Base64.c -------------------------------------------------------------------------------- /BOIT Server/CommandEvent.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/CommandEvent.h -------------------------------------------------------------------------------- /BOIT Server/CommandManager.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/CommandManager.c -------------------------------------------------------------------------------- /BOIT Server/CommandManager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/CommandManager.h -------------------------------------------------------------------------------- /BOIT Server/Command_about.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include"CommandManager.h" 3 | #include"APITransfer.h" 4 | #include"InlineCommand.h" 5 | 6 | int CmdMsg_about_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg) 7 | { 8 | SendBackMessage(boitSession, L"BOIT 2.0 MadeBy kernel.bin with ❤"); 9 | SendBackMessage(boitSession, L"OI + BOT = BOIT"); 10 | SendBackMessage(boitSession, L"[CQ:share,url=https://github.com/kernelbin/BOIT,title=BOIT 项目 Github 链接,content=An open sourced bot for OIers,image=image=https://q1.qlogo.cn/g?b=qq&nk=1160386205&s=640]"); 11 | 12 | return 0; 13 | } -------------------------------------------------------------------------------- /BOIT Server/Command_admin.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Command_admin.c -------------------------------------------------------------------------------- /BOIT Server/Command_boast.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Command_boast.c -------------------------------------------------------------------------------- /BOIT Server/Command_cat.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Command_cat.c -------------------------------------------------------------------------------- /BOIT Server/Command_codeforces.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Command_codeforces.c -------------------------------------------------------------------------------- /BOIT Server/Command_help.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Command_help.c -------------------------------------------------------------------------------- /BOIT Server/Command_luogu.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Command_luogu.c -------------------------------------------------------------------------------- /BOIT Server/Command_oier.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Command_oier.c -------------------------------------------------------------------------------- /BOIT Server/Command_q_and_a.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Command_q_and_a.c -------------------------------------------------------------------------------- /BOIT Server/Command_qwq.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include"CommandManager.h" 3 | #include"APITransfer.h" 4 | #include"InlineCommand.h" 5 | #include"Corpus.h" 6 | 7 | 8 | typedef struct __tagQwQMsgAndChangce 9 | { 10 | WCHAR* Msg; 11 | int Chance; 12 | }QWQ_MSG_AND_CHANCE; 13 | 14 | QWQ_MSG_AND_CHANCE QwQMessage[] = 15 | { 16 | L"pwp", 5, 17 | L"qwq", 5, 18 | L"owo", 5, 19 | L"/w\\", 5, 20 | L"QwQ", 5, 21 | L"/qwq\\", 3, 22 | L"ヾ(≧▽≦*)o", 3, 23 | L"`(*>﹏<*)′", 3, 24 | L"(*≧▽≦)o☆" , 3, 25 | L"(*/ω\*)", 3, 26 | L"(。・∀・)ノ", 2, 27 | L"_(:з」∠)_", 2, 28 | L"(*´▽`*)❀", 2, 29 | L"(๑• . •๑)◞♡", 2, 30 | L"(´• ᵕ •`)*✲゚*", 2, 31 | L"(´,,•∀•,,`)", 2, 32 | L"呐", 1, 33 | L"呐呐呐", 1, 34 | L"呐呐呐qwq", 1, 35 | L"诶嘿嘿", 1, 36 | L"诶嘿嘿qwq", 1, 37 | L"喵喵喵", 1, 38 | L"嗷嗷", 1, 39 | L"汪汪", 1, 40 | L"小fafa给你 🌸", 1, 41 | }; 42 | 43 | 44 | int CmdMsg_qwq_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg) 45 | { 46 | int TotChance = 0; 47 | for (int i = 0; i < _countof(QwQMessage); i++) 48 | { 49 | TotChance += QwQMessage[i].Chance; 50 | } 51 | 52 | int rand_num = rand() % TotChance; 53 | 54 | for (int i = 0; i < _countof(QwQMessage); i++) 55 | { 56 | if (rand_num < QwQMessage[i].Chance) 57 | { 58 | SendBackMessage(boitSession, QwQMessage[i].Msg); 59 | break; 60 | } 61 | rand_num -= QwQMessage[i].Chance; 62 | } 63 | 64 | return 0; 65 | } -------------------------------------------------------------------------------- /BOIT Server/Command_run.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Command_run.c -------------------------------------------------------------------------------- /BOIT Server/Command_run.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Command_run.h -------------------------------------------------------------------------------- /BOIT Server/Command_runcode.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Command_runcode.c -------------------------------------------------------------------------------- /BOIT Server/Command_savecode.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Command_savecode.c -------------------------------------------------------------------------------- /BOIT Server/Command_sponsor.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Command_sponsor.c -------------------------------------------------------------------------------- /BOIT Server/Command_stop.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include"CommandManager.h" 3 | #include"APITransfer.h" 4 | #include"InlineCommand.h" 5 | #include"Global.h" 6 | #include"DirManagement.h" 7 | #include"Corpus.h" 8 | int CmdMsg_stop_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg) 9 | { 10 | if (CheckUserToken(GetBOITSessionQQID(boitSession), L"PrivilegeBOITStop")) 11 | { 12 | SendBackMessage(boitSession, L"Goodbye~"); 13 | SetEvent(hEventServerStop); 14 | } 15 | else 16 | { 17 | SendBackMessage(boitSession, Corpus_NoPrivilege()); 18 | } 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /BOIT Server/Command_version.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Command_version.c -------------------------------------------------------------------------------- /BOIT Server/Corpus.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include"Corpus.h" 3 | 4 | 5 | WCHAR * Corpus_NoPrivilegeMessage[] = { 6 | L"Oops... 您没有适当的权限进行操作", 7 | L"您没有权限执行该指令", 8 | L"不要 我才不听你的话 哼~", 9 | L"不要这样嘛...", 10 | L"刚刚你说啥...? 我没听清?", 11 | L"你坏坏 我不听你的", 12 | L"我不听你的 请你吃桃子", 13 | L"爪巴", 14 | L"爬", 15 | L"有内鬼,终止执行指令。", 16 | L"才不要呢~", 17 | L"You are not in the sudoers file. This incident will be reported.", 18 | L"Unable to do this, are you root?" 19 | }; 20 | 21 | 22 | WCHAR* Corpus_WhereIsInputMessage[] = { 23 | L"我好饿,喂给我的输入数据去哪里了qaq", 24 | L"好饿.....", 25 | L"输入数据去哪里了qaq", 26 | L"输入数据呢qwq", 27 | L"qaq?", 28 | L"不输入拉倒", 29 | L"不输入拉倒,不等你了" 30 | }; 31 | 32 | 33 | WCHAR* Corpus_CodeNotFoundMessage[] = { 34 | L"诶?代码找不到了诶~", 35 | L"这里没有你的代码...", 36 | L"你的代码去哪里了诶...?", 37 | L"找不到你的代码了,要不先存一份代码?" 38 | }; 39 | 40 | 41 | WCHAR* Corpus_FunctionDevingMessage[] = { 42 | L"前方施工,暂时无法通行", 43 | L"不行不行,这个还不能用!", 44 | L"这里的代码还没写好的样子诶", 45 | L"kernel.bin还在咕咕咕,快去催他写代码!", 46 | L"kernel.bin什么时候才能写好这个功能?", 47 | L"这个功能还在开发呢,可能永远也不会上线了", 48 | L"该功能还在开发中", 49 | L"kernel.bin又咕咕咕了" 50 | }; 51 | 52 | //语料库 53 | 54 | 55 | 56 | WCHAR* Corpus_NoPrivilege() 57 | { 58 | return Corpus_NoPrivilegeMessage[rand() % _countof(Corpus_NoPrivilegeMessage)]; 59 | } 60 | 61 | 62 | WCHAR* Corpus_WhereIsInput() 63 | { 64 | return Corpus_WhereIsInputMessage[rand() % _countof(Corpus_WhereIsInputMessage)]; 65 | } 66 | 67 | 68 | 69 | WCHAR* Corpus_CodeNotFound() 70 | { 71 | return Corpus_CodeNotFoundMessage[rand() % _countof(Corpus_CodeNotFoundMessage)]; 72 | } 73 | 74 | 75 | WCHAR* Corpus_FunctionDeving() 76 | { 77 | return Corpus_FunctionDevingMessage[rand() % _countof(Corpus_FunctionDevingMessage)]; 78 | } -------------------------------------------------------------------------------- /BOIT Server/Corpus.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | 5 | WCHAR* Corpus_NoPrivilege(); 6 | 7 | WCHAR* Corpus_WhereIsInput(); 8 | 9 | WCHAR* Corpus_CodeNotFound(); 10 | 11 | WCHAR* Corpus_FunctionDeving(); 12 | -------------------------------------------------------------------------------- /BOIT Server/DirManagement.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/DirManagement.c -------------------------------------------------------------------------------- /BOIT Server/DirManagement.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/DirManagement.h -------------------------------------------------------------------------------- /BOIT Server/Global.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Global.h -------------------------------------------------------------------------------- /BOIT Server/HandleBOITCode.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/HandleBOITCode.c -------------------------------------------------------------------------------- /BOIT Server/HandleBOITCode.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/HandleBOITCode.h -------------------------------------------------------------------------------- /BOIT Server/InlineCommand.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/InlineCommand.c -------------------------------------------------------------------------------- /BOIT Server/InlineCommand.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include"CommandManager.h" 4 | 5 | int CmdMsg_qwq_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR * Msg); 6 | int CmdMsg_boast_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 7 | int CmdMsg_help_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 8 | int CmdMsg_run_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 9 | int CmdMsg_savecode_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 10 | int CmdMsg_runcode_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 11 | int CmdMsg_showcode_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 12 | int CmdMsg_stop_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 13 | int CmdMsg_q_and_a_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 14 | int CmdMsg_about_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 15 | int CmdMsg_donate_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 16 | int CmdMsg_cat_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 17 | int CmdMsg_meow_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 18 | int CmdMsg_version_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 19 | int CmdMsg_oier_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 20 | int CmdMsg_codeforces_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 21 | int CmdMsg_luogu_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 22 | int CmdMsg_admin_Proc(pBOIT_COMMAND pCmd, pBOIT_SESSION boitSession, WCHAR* Msg); 23 | int CmdEvent_run_Proc(pBOIT_COMMAND pCmd, UINT Event, PARAMA ParamA, PARAMB ParamB); 24 | int CmdEvent_oier_Proc(pBOIT_COMMAND pCmd, UINT Event, PARAMA ParamA, PARAMB ParamB); 25 | int CmdEvent_codeforces_Proc(pBOIT_COMMAND pCmd, UINT Event, PARAMA ParamA, PARAMB ParamB); 26 | int CmdEvent_luogu_Proc(pBOIT_COMMAND pCmd, UINT Event, PARAMA ParamA, PARAMB ParamB); -------------------------------------------------------------------------------- /BOIT Server/MessageReply.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/MessageReply.c -------------------------------------------------------------------------------- /BOIT Server/MessageWatch.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/MessageWatch.c -------------------------------------------------------------------------------- /BOIT Server/MessageWatch.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/MessageWatch.h -------------------------------------------------------------------------------- /BOIT Server/PerCommandData.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/PerCommandData.c -------------------------------------------------------------------------------- /BOIT Server/PerGroupData.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/PerGroupData.c -------------------------------------------------------------------------------- /BOIT Server/PerUserData.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/PerUserData.c -------------------------------------------------------------------------------- /BOIT Server/Pic.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/Pic.cpp -------------------------------------------------------------------------------- /BOIT Server/Pic.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef __cplusplus 4 | extern "C" BOOL SaveHDCToFile(HDC hDC, LPRECT lpRect, WCHAR FilePath[]); 5 | extern "C" BOOL InitGDIPlus(); 6 | extern "C" BOOL CleanupGDIPlus(); 7 | #else 8 | BOOL SaveHDCToFile(HDC hDC, LPRECT lpRect, WCHAR FilePath[]); 9 | BOOL InitGDIPlus(); 10 | BOOL CleanupGDIPlus(); 11 | #endif -------------------------------------------------------------------------------- /BOIT Server/RecvEventHandler.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/RecvEventHandler.c -------------------------------------------------------------------------------- /BOIT Server/RecvEventHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | int StartRecvEventHandler(); 4 | -------------------------------------------------------------------------------- /BOIT Server/RegisterRW.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/RegisterRW.c -------------------------------------------------------------------------------- /BOIT Server/RegisterRW.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | 5 | int RegisterRead(WCHAR* BaseDir); 6 | 7 | int RegisterWrite(WCHAR* BaseDir); 8 | 9 | int InitializeSettings(WCHAR* BaseDir); 10 | 11 | int ClearSettings(); 12 | -------------------------------------------------------------------------------- /BOIT Server/RemoveCQEscapeChar.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/RemoveCQEscapeChar.c -------------------------------------------------------------------------------- /BOIT Server/RemoveCQEscapeChar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | BOOL RemoveCQEscapeChar(WCHAR* Text); -------------------------------------------------------------------------------- /BOIT Server/SendEventDispatch.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/SendEventDispatch.c -------------------------------------------------------------------------------- /BOIT Server/SendEventDispatch.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include"SharedMemStruct.h" 3 | 4 | int SendEventPrivateMsg(long long QQID, WCHAR* Msg); 5 | 6 | int SendEventGroupMsg(long long GroupID, WCHAR* Msg); 7 | 8 | int SendEventGetGroupMemberInfo(long long GroupID, long long QQID, BOOL NoCache, pBOIT_GROUPMEMBER_INFO GroupMemberInfo); 9 | 10 | int SendEventGetStrangerInfo(long long QQID, BOOL NoCache, pBOIT_STRANGER_INFO StrangerInfo); 11 | 12 | int SendEventRetrieveCQPath(WCHAR* Path); 13 | -------------------------------------------------------------------------------- /BOIT Server/ServerMain.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include"EstablishConn.h" 4 | #include"Global.h" 5 | #include"RecvEventHandler.h" 6 | #include"RegisterRW.h" 7 | #include"DirManagement.h" 8 | #include"Settings.h" 9 | #include 10 | #include"CommandManager.h" 11 | #include 12 | #include"SimpleSandbox.h" 13 | #include 14 | #include"MessageWatch.h" 15 | #include"Pic.h" 16 | 17 | //**************************************************************************************************************** 18 | #include"SendEventDispatch.h" 19 | 20 | 21 | BOOL StartInputThread(); 22 | 23 | unsigned __stdcall HandleInputThread(LPVOID Args); 24 | 25 | HANDLE hInputThread; // 输入线程句柄 26 | 27 | BOOL ConsoleQueryYesNo(char* QueryText); 28 | 29 | 30 | int main() 31 | { 32 | int ch_ret; 33 | puts("BOIT Server正在启动\n"); 34 | 35 | InitGDIPlus(); 36 | InitializeSandbox(2, 2); 37 | 38 | InitializeMessageWatch(); 39 | InitializeCommandManager(); 40 | InitMessageReply(); 41 | 42 | RegisterInlineCommand();//注册所有内置指令 43 | 44 | //读取注册表,检查配置 45 | switch (RegisterRead(GetBOITBaseDir())) 46 | { 47 | case SETTINGS_LOADED: 48 | puts("注册表加载成功\n"); 49 | InitBOITDirVar(); 50 | break; 51 | case SETTINGS_ERR_OLD_SOFTWARE: 52 | puts("检测到您正在使用的软件比之前使用过的版本更低。请使用高版本的软件\n如果需要使用低版本的软件请先在高版本软件中卸载之前的安装。\n"); 53 | puts("按任意键退出程序"); 54 | ch_ret = _getch(); 55 | return 0; 56 | case SETTINGS_ERR_OUT_OF_DATE: 57 | puts("检测到您正在使用新版本的软件。请先用旧版本软件移除之前的安装!"); 58 | puts("按任意键退出程序"); 59 | ch_ret = _getch(); 60 | return 0; 61 | case SETTINGS_ERROR: 62 | if (ConsoleQueryYesNo("注册表加载失败,是否清空设置并初始化 ?") == FALSE) 63 | { 64 | puts("按任意键退出程序"); 65 | ch_ret = _getch(); 66 | return 0; 67 | } 68 | //清理注册表 69 | if (ClearSettings() == SETTINGS_ERROR) 70 | { 71 | puts("清空设置失败,按任意键退出程序"); 72 | ch_ret = _getch(); 73 | return 0; 74 | } 75 | //fall 76 | case SETTINGS_NOT_FOUND: 77 | { 78 | puts("欢迎使用BOIT qwq\n"); 79 | char InBaseDir[MAX_PATH + 4] = { 0 }; 80 | while (1) 81 | { 82 | puts("请输入BOIT目录(无需引号,完整输入一行后换行)"); 83 | scanf_s("%[^\n]", &InBaseDir, MAX_PATH); 84 | ch_ret = getchar();//读掉 \n 85 | if (IsPathDirA(InBaseDir) == TRUE) 86 | { 87 | PathSimplifyA(InBaseDir); 88 | PathAddBackslashA(InBaseDir); 89 | break; 90 | } 91 | puts("这真的是一个目录吗?"); 92 | } 93 | 94 | printf("将在目录 %s 初始化BOIT\n", InBaseDir); 95 | PathAppendA(InBaseDir, "BOIT\\"); 96 | 97 | 98 | MultiByteToWideChar(CP_ACP, 0, InBaseDir, -1, GetBOITBaseDir(), MAX_PATH); 99 | 100 | if (InitializeSettings(GetBOITBaseDir()) != SETTINGS_INITIALIZED) 101 | { 102 | //Oops 103 | puts("初始化注册表失败,按任意键退出程序"); 104 | ch_ret = _getch(); 105 | return 0; 106 | } 107 | else 108 | { 109 | //初始化目录等 110 | //TODO: 检查是不是空目录 111 | InitBOITDirVar(); 112 | 113 | InitBOITDir(); 114 | } 115 | break; 116 | } 117 | 118 | } 119 | 120 | bBOITRemove = 0;//是否卸载程序标识 121 | 122 | BroadcastCommandEvent(EC_CMDLOAD, 0, 0); 123 | 124 | InitServerState(); 125 | InitSendEventDispatch();; 126 | InitEstablishConn(); 127 | 128 | StartInputThread(); // 启动控制台输入线程 129 | 130 | if (TryEstablishConn(hEventServerStop) != -1) 131 | { 132 | puts("连接成功!\n"); 133 | WCHAR Path[MAX_PATH]; 134 | SendEventRetrieveCQPath(Path); 135 | PathAppendW(Path, L"..\\..\\.."); 136 | PathCanonicalizeW(GetCQBaseDir(), Path); 137 | InitCQDirVar(); 138 | StartRecvEventHandler(); 139 | 140 | WaitForSingleObject(hEventServerStop, INFINITE); 141 | } 142 | 143 | 144 | 145 | //清理工作 146 | 147 | TerminateInputThread(); 148 | BroadcastCommandEvent(EC_CMDFREE, 0, 0); 149 | FinalizeCommandManager(); 150 | FinalizeMessageWatch(); 151 | FinalizeSandbox(); 152 | 153 | CleanupGDIPlus(); 154 | 155 | //检查是否卸载 156 | if (bBOITRemove) 157 | { 158 | puts("清理中qaq"); 159 | if (ClearSettings() == SETTINGS_ERROR) 160 | { 161 | puts("清理注册表失败,可能是权限不足导致的。请手动清理注册表项。按任意键退出程序"); 162 | ch_ret = _getch(); 163 | return 0; 164 | } 165 | if (RemoveDirIfExist(GetBOITBaseDir()) == FALSE) 166 | { 167 | puts("清理BOIT目录失败,可能是权限不足导致的。请手动清理文件夹。按任意键退出程序"); 168 | ch_ret = _getch(); 169 | return 0; 170 | } 171 | 172 | puts("BOIT注册表项和文件夹已从您的计算机上移除。"); 173 | puts("CoolQ插件和该程序本身不会自动移除,如果需要请手动删除他们。"); 174 | puts("感谢使用!按任意键退出程序"); 175 | ch_ret = _getch(); 176 | return 0; 177 | } 178 | else 179 | { 180 | //puts("按任意键退出程序"); 181 | //ch_ret = _getch(); 182 | } 183 | return 0; 184 | } 185 | 186 | BOOL ConsoleQueryYesNo(char* QueryText) 187 | { 188 | int ch_ret; 189 | while (1) 190 | { 191 | printf(QueryText); 192 | printf(" (y/n)\n"); 193 | char Answer[128] = { 0 }; 194 | scanf_s("%[^\n]", &Answer, _countof(Answer) - 1); 195 | ch_ret = getchar();//读掉那个换行 196 | if (strcmp(Answer, "y") == 0 || 197 | strcmp(Answer, "Y") == 0 || 198 | strcmp(Answer, "yes") == 0 || 199 | strcmp(Answer, "Yes") == 0 200 | ) 201 | { 202 | return TRUE; 203 | } 204 | else if (strcmp(Answer, "n") == 0 || 205 | strcmp(Answer, "N") == 0 || 206 | strcmp(Answer, "no") == 0 || 207 | strcmp(Answer, "No") == 0 208 | ) 209 | { 210 | return FALSE; 211 | } 212 | } 213 | return FALSE; 214 | } 215 | 216 | BOOL StartInputThread() 217 | { 218 | hInputThread = _beginthreadex(0, 0, HandleInputThread, 0, 0, 0); 219 | return 0; 220 | } 221 | 222 | BOOL TerminateInputThread() 223 | { 224 | if (hInputThread) 225 | { 226 | if (WaitForSingleObject(hInputThread, 0) == WAIT_TIMEOUT) 227 | { 228 | TerminateThread(hInputThread, 0); 229 | WaitForSingleObject(hInputThread, INFINITE); 230 | } 231 | } 232 | return 0; 233 | } 234 | 235 | unsigned __stdcall HandleInputThread(LPVOID Args) 236 | { 237 | int ch_ret; 238 | while (1) 239 | { 240 | char InputCommand[128]; 241 | printf("> "); 242 | int bMatch = scanf_s("%[^\n]", InputCommand, _countof(InputCommand)); 243 | ch_ret = getchar(); 244 | if (bMatch == 1) 245 | { 246 | if (_strcmpi(InputCommand, "stop") == 0) 247 | { 248 | puts("Goodbye"); 249 | SetEvent(hEventServerStop); 250 | return 0; 251 | } 252 | else if (_strcmpi(InputCommand, "help") == 0) 253 | { 254 | puts("帮助信息:\n\nstop: 关闭BOIT\nremove: 卸载BOIT\nhelp: 显示帮助信息"); 255 | } 256 | else if (_strcmpi(InputCommand, "remove") == 0) 257 | { 258 | if (ConsoleQueryYesNo("这将关闭BOIT从注册表中清除所有BOIT配置项,并移除BOIT目录。确定吗?") == TRUE) 259 | { 260 | bBOITRemove = TRUE; 261 | SetEvent(hEventServerStop); 262 | puts("关闭BOIT中"); 263 | return 0; 264 | //main函数退出的时候会检测bBOITRemove 265 | } 266 | } 267 | } 268 | } 269 | } 270 | 271 | -------------------------------------------------------------------------------- /BOIT Server/ServerState.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/ServerState.c -------------------------------------------------------------------------------- /BOIT Server/SessionManage.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include"SessionManage.h" 3 | 4 | pBOIT_SESSION InitBOITSession(long long GroupID, long long QQID, WCHAR* AnonymousName, int SubType) 5 | { 6 | pBOIT_SESSION boitSession = 0; 7 | boitSession = malloc(sizeof(BOIT_SESSION)); 8 | if (!boitSession) 9 | { 10 | return 0; 11 | } 12 | boitSession->GroupID = GroupID; 13 | boitSession->QQID = QQID; 14 | boitSession->SubType = SubType; 15 | if (AnonymousName && AnonymousName[0]) 16 | { 17 | wcscpy_s(boitSession->AnonymousName, BOIT_MAX_NICKLEN, AnonymousName); 18 | } 19 | else 20 | { 21 | boitSession->AnonymousName[0] = 0; 22 | } 23 | 24 | return boitSession; 25 | } 26 | 27 | pBOIT_SESSION DuplicateBOITSession(pBOIT_SESSION SourceSession) 28 | { 29 | pBOIT_SESSION boitSession = 0; 30 | boitSession = malloc(sizeof(BOIT_SESSION)); 31 | if (!boitSession) 32 | { 33 | return 0; 34 | } 35 | boitSession->GroupID = SourceSession->GroupID; 36 | boitSession->QQID = SourceSession->QQID; 37 | boitSession->SubType = SourceSession->SubType; 38 | if (SourceSession->AnonymousName && SourceSession->AnonymousName[0]) 39 | { 40 | wcscpy_s(boitSession->AnonymousName, BOIT_MAX_NICKLEN, SourceSession->AnonymousName); 41 | } 42 | else 43 | { 44 | boitSession->AnonymousName[0] = 0; 45 | } 46 | return boitSession; 47 | } 48 | 49 | BOOL FreeBOITSession(pBOIT_SESSION boitSession) 50 | { 51 | if (boitSession) 52 | { 53 | free(boitSession); 54 | } 55 | return TRUE; 56 | } 57 | 58 | int GetBOITSessionType(pBOIT_SESSION boitSession) 59 | { 60 | if (boitSession->GroupID) 61 | { 62 | if (boitSession->QQID) 63 | { 64 | return BOITSESS_TYPE_GROUP; 65 | } 66 | else 67 | { 68 | return BOITSESS_TYPE_ERROR; 69 | } 70 | } 71 | else 72 | { 73 | if (boitSession->QQID) 74 | { 75 | return BOITSESS_TYPE_PRIVATE; 76 | } 77 | else 78 | { 79 | return BOITSESS_TYPE_NULL; 80 | } 81 | } 82 | } 83 | 84 | 85 | 86 | 87 | long long GetBOITSessionQQID(pBOIT_SESSION boitSession) 88 | { 89 | return boitSession->QQID; 90 | } 91 | 92 | long long GetBOITSessionGroupID(pBOIT_SESSION boitSession) 93 | { 94 | return boitSession->GroupID; 95 | } 96 | 97 | -------------------------------------------------------------------------------- /BOIT Server/SessionManage.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/SessionManage.h -------------------------------------------------------------------------------- /BOIT Server/SimpleSandbox.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/SimpleSandbox.c -------------------------------------------------------------------------------- /BOIT Server/SimpleSandbox.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/SimpleSandbox.h -------------------------------------------------------------------------------- /BOIT Server/TokenManage.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/TokenManage.c -------------------------------------------------------------------------------- /BOIT Server/VBuffer.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Server/VBuffer.c -------------------------------------------------------------------------------- /BOIT Server/VBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | typedef struct __tagVBuffer 5 | { 6 | PBYTE Data; 7 | DWORD Length; 8 | DWORD Capibility; 9 | }VBUF, *pVBUF; 10 | 11 | pVBUF AllocVBuf(); 12 | BOOL FreeVBuf(pVBUF pVBuf); 13 | BOOL AdjustVBuf(pVBUF pVBuf, DWORD Size); 14 | BOOL AddSizeVBuf(pVBUF pVBuf, DWORD AddSize); 15 | DWORD VBufGetCorrectSize(DWORD Size); 16 | 17 | BOOL VBufferAppendStringW(pVBUF VBuffer, WCHAR* String); -------------------------------------------------------------------------------- /BOIT Server/WaitForConnThread.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include"EstablishConn.h" 4 | #include"Global.h" 5 | 6 | 7 | 8 | unsigned __stdcall WaitForConnThread(void* Args) 9 | { 10 | InitEstablishConn(); 11 | TryEstablishConn(NULL); 12 | StartSendEventHandler(); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /BOIT Shared/BOIT Shared.vcxitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | {b17851fb-4678-46a9-afbb-26eba1a293cf} 7 | BOIT Event Shared 8 | 9 | 10 | 11 | %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /BOIT Shared/BOIT Shared.vcxitems.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {b16a76ed-a048-4b9c-8a22-376223bef1e8} 6 | 7 | 8 | 9 | 10 | 源文件 11 | 12 | 13 | 源文件 14 | 15 | 16 | 源文件 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 26 | 27 | 源文件 28 | 29 | 30 | -------------------------------------------------------------------------------- /BOIT Shared/BOITEventType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #define BOIT_EVENT_RECV_PRIVATE 1 5 | #define BOIT_EVENT_RECV_GROUP 2 6 | 7 | #define BOIT_EVENT_SEND_PRIVATE 101 8 | #define BOIT_EVENT_SEND_GROUP 102 9 | #define BOIT_EVENT_SEND_GET_GROUPMEMBER_INFO 103 10 | #define BOIT_EVENT_SEND_GET_STRANGER_INFO 104 11 | #define BOIT_EVENT_SEND_RETRIEVE_CQPATH 105 12 | 13 | -------------------------------------------------------------------------------- /BOIT Shared/BOITInfoMaxDef.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Shared/BOITInfoMaxDef.h -------------------------------------------------------------------------------- /BOIT Shared/EstablishConn.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Shared/EstablishConn.c -------------------------------------------------------------------------------- /BOIT Shared/EstablishConn.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Shared/EstablishConn.h -------------------------------------------------------------------------------- /BOIT Shared/ObjectName.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define OBJECT_NAME_SUFFIX TEXT("CD965130-EACC-4893-B7B9-268D1EF160E3") 4 | 5 | #define GET_OBJ_NAME(a) OBJECT_NAME_SUFFIX TEXT(#a) -------------------------------------------------------------------------------- /BOIT Shared/SharedMemStruct.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Shared/SharedMemStruct.h -------------------------------------------------------------------------------- /BOIT Version/BOIT Version.vcxitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | {c8f4745c-7444-428b-b149-2765b7ad17e2} 7 | 8 | 9 | 10 | %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /BOIT Version/BOIT Version.vcxitems.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {186ebd13-96ef-4bc8-a7a4-638e6155f69e} 6 | 7 | 8 | 9 | 10 | 设置相关 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /BOIT Version/BOITVersion.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Version/BOITVersion.h -------------------------------------------------------------------------------- /BOIT Version/Settings.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/BOIT Version/Settings.h -------------------------------------------------------------------------------- /BOIT.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29613.14 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BOIT DLL", "BOIT DLL\BOIT DLL.vcxproj", "{CCE394D1-964D-4B5F-BEB2-7BB1F016B268}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BOIT Server", "BOIT Server\BOIT Server.vcxproj", "{E971129E-1CA0-4C70-8208-304B32243F91}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BOIT Event Shared", "BOIT Shared\BOIT Shared.vcxitems", "{B17851FB-4678-46A9-AFBB-26EBA1A293CF}" 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BOIT Version", "BOIT Version\BOIT Version.vcxitems", "{C8F4745C-7444-428B-B149-2765B7AD17E2}" 13 | EndProject 14 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StringProcess", "StringProcess\StringProcess.vcxitems", "{66FF8FA6-F3F7-41CF-9554-56AEEE1DDA77}" 15 | EndProject 16 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cJSON", "cJSON\cJSON.vcxitems", "{19899D8B-F0BB-4AFA-B671-1CCB10C98AA5}" 17 | EndProject 18 | Global 19 | GlobalSection(SharedMSBuildProjectFiles) = preSolution 20 | cJSON\cJSON.vcxitems*{19899d8b-f0bb-4afa-b671-1ccb10c98aa5}*SharedItemsImports = 9 21 | StringProcess\StringProcess.vcxitems*{66ff8fa6-f3f7-41cf-9554-56aeee1dda77}*SharedItemsImports = 9 22 | BOIT Shared\BOIT Shared.vcxitems*{b17851fb-4678-46a9-afbb-26eba1a293cf}*SharedItemsImports = 9 23 | BOIT Version\BOIT Version.vcxitems*{c8f4745c-7444-428b-b149-2765b7ad17e2}*SharedItemsImports = 9 24 | BOIT Shared\BOIT Shared.vcxitems*{cce394d1-964d-4b5f-beb2-7bb1f016b268}*SharedItemsImports = 4 25 | BOIT Version\BOIT Version.vcxitems*{cce394d1-964d-4b5f-beb2-7bb1f016b268}*SharedItemsImports = 4 26 | StringProcess\StringProcess.vcxitems*{cce394d1-964d-4b5f-beb2-7bb1f016b268}*SharedItemsImports = 4 27 | BOIT Shared\BOIT Shared.vcxitems*{e971129e-1ca0-4c70-8208-304b32243f91}*SharedItemsImports = 4 28 | BOIT Version\BOIT Version.vcxitems*{e971129e-1ca0-4c70-8208-304b32243f91}*SharedItemsImports = 4 29 | cJSON\cJSON.vcxitems*{e971129e-1ca0-4c70-8208-304b32243f91}*SharedItemsImports = 4 30 | StringProcess\StringProcess.vcxitems*{e971129e-1ca0-4c70-8208-304b32243f91}*SharedItemsImports = 4 31 | EndGlobalSection 32 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 33 | Debug|x64 = Debug|x64 34 | Debug|x86 = Debug|x86 35 | Release|x64 = Release|x64 36 | Release|x86 = Release|x86 37 | EndGlobalSection 38 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 39 | {CCE394D1-964D-4B5F-BEB2-7BB1F016B268}.Debug|x64.ActiveCfg = Debug|x64 40 | {CCE394D1-964D-4B5F-BEB2-7BB1F016B268}.Debug|x64.Build.0 = Debug|x64 41 | {CCE394D1-964D-4B5F-BEB2-7BB1F016B268}.Debug|x86.ActiveCfg = Debug|Win32 42 | {CCE394D1-964D-4B5F-BEB2-7BB1F016B268}.Debug|x86.Build.0 = Debug|Win32 43 | {CCE394D1-964D-4B5F-BEB2-7BB1F016B268}.Release|x64.ActiveCfg = Release|x64 44 | {CCE394D1-964D-4B5F-BEB2-7BB1F016B268}.Release|x64.Build.0 = Release|x64 45 | {CCE394D1-964D-4B5F-BEB2-7BB1F016B268}.Release|x86.ActiveCfg = Release|Win32 46 | {CCE394D1-964D-4B5F-BEB2-7BB1F016B268}.Release|x86.Build.0 = Release|Win32 47 | {E971129E-1CA0-4C70-8208-304B32243F91}.Debug|x64.ActiveCfg = Debug|x64 48 | {E971129E-1CA0-4C70-8208-304B32243F91}.Debug|x64.Build.0 = Debug|x64 49 | {E971129E-1CA0-4C70-8208-304B32243F91}.Debug|x86.ActiveCfg = Debug|Win32 50 | {E971129E-1CA0-4C70-8208-304B32243F91}.Debug|x86.Build.0 = Debug|Win32 51 | {E971129E-1CA0-4C70-8208-304B32243F91}.Release|x64.ActiveCfg = Release|x64 52 | {E971129E-1CA0-4C70-8208-304B32243F91}.Release|x64.Build.0 = Release|x64 53 | {E971129E-1CA0-4C70-8208-304B32243F91}.Release|x86.ActiveCfg = Release|Win32 54 | {E971129E-1CA0-4C70-8208-304B32243F91}.Release|x86.Build.0 = Release|Win32 55 | EndGlobalSection 56 | GlobalSection(SolutionProperties) = preSolution 57 | HideSolutionNode = FALSE 58 | EndGlobalSection 59 | GlobalSection(ExtensibilityGlobals) = postSolution 60 | SolutionGuid = {D1BF9AB3-51C2-4A15-AEC3-CE8A9DBC8622} 61 | EndGlobalSection 62 | EndGlobal 63 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 杨赫 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BOIT 2 | yh蒟蒻写的给OIers用的一个bot,OI Bot的第二版。 3 | 4 | A bot running on QQ (IM software, popular in China) written by YH for OIers (Who learn Olympiad in Informatics) 5 | 6 | # Attention 7 | 8 | RIP CoolQ. 近期我不会继续开发这个 bot(避避风头). 如果 TX 一段时间内没有继续打压各类第三方 bot 平台,我会开始着手开发第三版的bot,并迁移至基于 HTTP API 的 mirai,并为 bot 添加更多新功能。希望那时能继续得到大家的支持! 9 | 10 | 11 | # features 12 | **小!!!** 目前可执行文件和dll打包大小不到400KB 13 | 14 | **快!!!** 多线程架构并发处理指令,run等高性能要求指令使用IO完成端口负载均衡技术 15 | 16 | **功能强大** 内置沙盒,可以运行代码,支持输入数据等功能,内置查询OIer等功能,查询codeforces等功能 17 | 18 | **易于部署** 程序本身不需要任何依赖(除CoolQ),可轻易部署 19 | 20 | # Try it! 21 | 目前该bot部署在 QQ号 2068736261 上。可以加好友执行指令。(目前加好友审核是人工的,可能不会第一时间通过申请) 22 | 指令前缀是 '#' 用 "#help"指令查看帮助 23 | 24 | # 部署(CoolQ 他 SPFA 了) 25 | 从 [Release](https://github.com/kernelbin/BOIT/releases) 页面下载最新的Release,包括.cpk文件(CoolQ插件)和与您计算机位数相匹配的可执行文件(x86或x64) 26 | 27 | 在CoolQ官网注册账号,并下载 CoolQ Pro/Air (CoolQ Pro为收费版本,支持发送图片,语音等功能) 详见 [CoolQ社区](https://cqp.cc/) 28 | 29 | 将.cpk文件放入CoolQ插件目录 (位于Path_To_CoolQ\app\) 30 | 31 | 打开CoolQ,并登录您的CoolQ。(请右击CoolQ在任务栏中的图标,在菜单中选择 应用->应用管理 ,并确认 BOIT插件 已经启用) 32 | 33 | 启动从Release中下载的可执行文件(BOIT.Server.xxxx.exe)。第一次使用会需要输入 BOIT目录,(用于存储权限信息,配置信息,缓存编译文件等) 34 | 35 | 如果控制台显示 “连接成功!”,说明正常工作了。 36 | 37 | ## 替代解决方案 38 | 基于 [mirai](https://github.com/mamoe/mirai/tree/master) 的 [mirai native](https://github.com/iTXTech/mirai-native) 理论上来说暂时作为 CoolQ 的替代品。但我早期迁移 mirai 的工作并没有完全完成,是否能在最新版的 mirai native 上运行并没有测试过。你可以亲自去试试。 39 | 40 | # 注意!!!! 41 | - 目前由于技术问题,同时运行多个CoolQ,或者同时运行多个可执行文件(BOIT.Server.xxxx.exe)可能会导致不正常工作。在一台计算机上只能打开一个CoolQ和一个可执行文件。 42 | 43 | - 在一台计算机上第一次使用CoolQ登录某个账号,通常会出现消息发送不出去的情况。(CoolQ日志显示为发送,但实际没有收到消息)。这种情况下保持CoolQ在该IP地址多登录几次,等待数天即可解决。 44 | 45 | - 目前run指令使用的内置沙盒并没有限制读取权限。为了防止隐私泄露,请避免在可能存放有您的个人信息的计算机上启用run指令(最简单的办法就是不去配置#run指令) 46 | 47 | ## 如何配置编译指令?(#run指令) 48 | 安装好你需要的编译器或解释器。(BOIT目前没有内置任何编译器或解释器) 49 | 找到BOIT目录,在 "BOIT\CommandCfg\run\Compiler\" 目录下新建后缀为.cfg的文件,如 "gcc.cfg" 50 | 下面以gcc为例子 51 | 52 | ``` 53 | # 允许行首以井号开头的注释 54 | 55 | # 语言名称,允许以空格为分割存放多个。在#run /help的时候,只有第一个名称会显示 56 | Name=c gcc 57 | 58 | # 可以使用 Compile 或是 Script 59 | Type=Compile 60 | 61 | # 源代码文件后缀 62 | Suffix=.c 63 | 64 | # 编译或是运行指令 65 | Command=gcc %In -o %Out 66 | 67 | # 可选,源代码的编码格式,支持GB18030,UTF8和ANSI。默认GB18030 68 | SourceEncode = GB18030 69 | 70 | # 可选,标准输入输出编码格式,支持GB18030,UTF8和ANSI。默认GB18030 71 | OutputEncode = GB18030 72 | 73 | # 对于Type=Compile,Command为编译指令。 74 | # 对于Type=Script,Command为脚本运行指令。 75 | # 其中 %In会被扩展为源文件名,%Out会被扩展为可执行文件名称(.exe),%% 为 % 本身 76 | ``` 77 | 78 | 79 | ## contribute 80 | - 向他人介绍该项目,推广BOIT。 81 | 82 | - 部署BOIT并帮助进行测试,bug反馈等。 83 | 84 | - 提供好的 idea,或者是feature request 85 | 86 | - 参与BOIT的开发。(如果你熟悉Win32开发) 87 | 88 | - Sponsor Me!! 点击 GitHub 上的 Sponsor 按钮以赞助开发 BOIT 89 | 90 | ## todo 91 | - 指令插件化 92 | 93 | - 支持玩人力资源机 94 | 95 | - 支持沙盒文件读写权限控制 96 | 97 | - 支持洛谷查询 98 | 99 | - 支持OI wiki查询 100 | -------------------------------------------------------------------------------- /StringProcess/CommandProcess.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include"CommandProcess.h" 3 | 4 | 5 | int GetLineLen(WCHAR* String) 6 | { 7 | int i; 8 | for (i = 0;; i++) 9 | { 10 | if (String[i] == L'\r' || 11 | String[i] == L'\n' || 12 | String[i] == 0) 13 | { 14 | break; 15 | } 16 | } 17 | return i; 18 | } 19 | 20 | 21 | int GetLineSpaceLen(WCHAR* String) 22 | { 23 | int i; 24 | for (i = 0;; i++) 25 | { 26 | if (String[i] != L' ' && 27 | String[i] != L'\t') 28 | { 29 | break; 30 | } 31 | } 32 | return i; 33 | } 34 | 35 | 36 | int GetLineFeedLen(WCHAR* String) 37 | { 38 | int i; 39 | for (i = 0;; i++) 40 | { 41 | if (String[i] != L' ' && 42 | String[i] != L'\r' && 43 | String[i] != L'\n') 44 | { 45 | break; 46 | } 47 | } 48 | return i; 49 | } 50 | 51 | 52 | int GetCmdSpaceLen(WCHAR* String) 53 | { 54 | int i; 55 | for (i = 0;; i++) 56 | { 57 | if (String[i] != L' ' && 58 | String[i] != L'\r' && 59 | String[i] != L'\n' && 60 | String[i] != L'\t') 61 | { 62 | break; 63 | } 64 | } 65 | return i; 66 | } 67 | 68 | 69 | int GetCmdParamLen(WCHAR* String) 70 | { 71 | int i; 72 | for (i = 0;; i++) 73 | { 74 | if (String[i] == L' ' || 75 | String[i] == L'\r' || 76 | String[i] == L'\n' || 77 | String[i] == L'\t' || 78 | String[i] == 0) 79 | { 80 | break; 81 | } 82 | } 83 | return i; 84 | } 85 | 86 | 87 | int GetCmdParamWithEscapeLen(WCHAR* String) 88 | { 89 | int i; 90 | BOOL bInEscape = FALSE; 91 | for (i = 0;; i++) 92 | { 93 | if (String[i] == L'\r' || 94 | String[i] == L'\n' || 95 | String[i] == L'\t' || 96 | String[i] == 0) 97 | { 98 | break; 99 | } 100 | 101 | if (bInEscape) 102 | { 103 | if (String[i] == L'\"') 104 | { 105 | bInEscape = FALSE; 106 | } 107 | // L' ' is ignored 108 | else if (String[i] == L'\\' && String[i + 1] == L'\\') 109 | { 110 | i++; 111 | } 112 | else if (String[i] == L'\\' && String[i + 1] == L'\'') 113 | { 114 | i++; 115 | } 116 | else if (String[i] == L'\\' && String[i + 1] == L'\"') 117 | { 118 | i++; 119 | } 120 | } 121 | else 122 | { 123 | if (String[i] == L'\"') 124 | { 125 | bInEscape = TRUE; 126 | } 127 | else if (String[i] == L' ') 128 | { 129 | break; 130 | } 131 | } 132 | } 133 | return i; 134 | } 135 | 136 | 137 | int CmdParamUnescape(WCHAR* String, WCHAR* UnescapeStr) 138 | { 139 | int i = 0; 140 | int j = 0; 141 | BOOL bInEscape = FALSE; 142 | for (i = 0;; i++) 143 | { 144 | if (String[i] == L'\r' || 145 | String[i] == L'\n' || 146 | String[i] == L'\t' || 147 | String[i] == 0) 148 | { 149 | break; 150 | } 151 | 152 | if (bInEscape) 153 | { 154 | if (String[i] == L'\"') 155 | { 156 | bInEscape = FALSE; 157 | } 158 | // L' ' is ignored 159 | else if (String[i] == L'\\' && String[i + 1] == L'\\') 160 | { 161 | UnescapeStr[j++] = String[i + 1]; 162 | i++; 163 | } 164 | else if (String[i] == L'\\' && String[i + 1] == L'\'') 165 | { 166 | UnescapeStr[j++] = String[i + 1]; 167 | i++; 168 | } 169 | else if (String[i] == L'\\' && String[i + 1] == L'\"') 170 | { 171 | UnescapeStr[j++] = String[i + 1]; 172 | i++; 173 | } 174 | else 175 | { 176 | UnescapeStr[j++] = String[i]; 177 | } 178 | } 179 | else 180 | { 181 | if (String[i] == L'\"') 182 | { 183 | bInEscape = TRUE; 184 | } 185 | else if (String[i] == L' ') 186 | { 187 | break; 188 | } 189 | else 190 | { 191 | UnescapeStr[j++] = String[i]; 192 | } 193 | } 194 | } 195 | UnescapeStr[j++] = 0; 196 | return i; 197 | } 198 | 199 | 200 | int GetBOITCodeParamWithEscapeLen(WCHAR* String) 201 | { 202 | int i; 203 | BOOL bInEscape = FALSE; 204 | for (i = 0;; i++) 205 | { 206 | if (String[i] == L'\r' || 207 | String[i] == L'\n' || 208 | String[i] == L'\t' || 209 | String[i] == 0) 210 | { 211 | break; 212 | } 213 | 214 | if (bInEscape) 215 | { 216 | if (String[i] == L'\"') 217 | { 218 | bInEscape = FALSE; 219 | } 220 | // L' ' is ignored 221 | else if (String[i] == L'\\' && String[i + 1] == L'\\') 222 | { 223 | i++; 224 | } 225 | else if (String[i] == L'\\' && String[i + 1] == L'\'') 226 | { 227 | i++; 228 | } 229 | else if (String[i] == L'\\' && String[i + 1] == L'\"') 230 | { 231 | i++; 232 | } 233 | } 234 | else 235 | { 236 | if (String[i] == L'\"') 237 | { 238 | bInEscape = TRUE; 239 | } 240 | else if (String[i] == L' ') 241 | { 242 | break; 243 | } 244 | else if (String[i] == L',') 245 | { 246 | break; 247 | } 248 | else if (String[i] == L']') 249 | { 250 | break; 251 | } 252 | } 253 | } 254 | return i; 255 | } 256 | 257 | 258 | int BOITCodeParamUnescape(WCHAR* String, WCHAR* UnescapeStr) 259 | { 260 | int i = 0; 261 | int j = 0; 262 | BOOL bInEscape = FALSE; 263 | for (i = 0;; i++) 264 | { 265 | if (String[i] == L'\r' || 266 | String[i] == L'\n' || 267 | String[i] == L'\t' || 268 | String[i] == 0) 269 | { 270 | break; 271 | } 272 | 273 | if (bInEscape) 274 | { 275 | if (String[i] == L'\"') 276 | { 277 | bInEscape = FALSE; 278 | } 279 | // L' ' is ignored 280 | else if (String[i] == L'\\' && String[i + 1] == L'\\') 281 | { 282 | UnescapeStr[j++] = String[i + 1]; 283 | i++; 284 | } 285 | else if (String[i] == L'\\' && String[i + 1] == L'\'') 286 | { 287 | UnescapeStr[j++] = String[i + 1]; 288 | i++; 289 | } 290 | else if (String[i] == L'\\' && String[i + 1] == L'\"') 291 | { 292 | UnescapeStr[j++] = String[i + 1]; 293 | i++; 294 | } 295 | else 296 | { 297 | UnescapeStr[j++] = String[i]; 298 | } 299 | } 300 | else 301 | { 302 | if (String[i] == L'\"') 303 | { 304 | bInEscape = TRUE; 305 | } 306 | else if (String[i] == L' ') 307 | { 308 | break; 309 | } 310 | else if (String[i] == L',') 311 | { 312 | break; 313 | } 314 | else if (String[i] == L']') 315 | { 316 | break; 317 | } 318 | else 319 | { 320 | UnescapeStr[j++] = String[i]; 321 | } 322 | } 323 | } 324 | UnescapeStr[j++] = 0; 325 | return i; 326 | } 327 | -------------------------------------------------------------------------------- /StringProcess/CommandProcess.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int GetLineLen(WCHAR* String); 4 | 5 | int GetLineSpaceLen(WCHAR* String); 6 | 7 | int GetLineFeedLen(WCHAR* String); 8 | 9 | int GetCmdSpaceLen(WCHAR* String); 10 | 11 | int GetCmdParamLen(WCHAR* String); 12 | 13 | int GetCmdParamWithEscapeLen(WCHAR* String); 14 | 15 | int CmdParamUnescape(WCHAR* String, WCHAR* UnescapeStr); 16 | 17 | int GetBOITCodeParamWithEscapeLen(WCHAR* String); 18 | 19 | int BOITCodeParamUnescape(WCHAR* String, WCHAR* UnescapeStr); 20 | -------------------------------------------------------------------------------- /StringProcess/EncodeConvert.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/StringProcess/EncodeConvert.c -------------------------------------------------------------------------------- /StringProcess/EncodeConvert.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kernelbin/BOIT/7c440781dfc47c1b299d372ede6ade371bb54210/StringProcess/EncodeConvert.h -------------------------------------------------------------------------------- /StringProcess/StringProcess.vcxitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | {66ff8fa6-f3f7-41cf-9554-56aeee1dda77} 7 | 8 | 9 | 10 | %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /StringProcess/StringProcess.vcxitems.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {34bb2976-6cc8-4a1a-bd24-d06f6ef1fd07} 6 | 7 | 8 | {5e947021-f331-4e2a-9c62-4aecb3ae648f} 9 | 10 | 11 | {76202d39-88c7-4fa5-8e19-9d5ae00526d3} 12 | 13 | 14 | 15 | 16 | 字符集转换 17 | 18 | 19 | URI编码 20 | 21 | 22 | 指令解析 23 | 24 | 25 | 26 | 27 | 字符集转换 28 | 29 | 30 | URI编码 31 | 32 | 33 | 指令解析 34 | 35 | 36 | -------------------------------------------------------------------------------- /StringProcess/URIEncode.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | int URLEncode(const char* str, const int strSize, char* result, const int resultSize) 5 | { 6 | int i; 7 | int j = 0;//for result index 8 | char ch; 9 | 10 | if ((str == NULL) || (result == NULL) || (strSize <= 0) || (resultSize <= 0)) { 11 | return 0; 12 | } 13 | 14 | for (i = 0; (i < strSize) && (j < resultSize); ++i) { 15 | ch = str[i]; 16 | if (((ch >= 'A') && (ch < 'Z')) || 17 | ((ch >= 'a') && (ch < 'z')) || 18 | ((ch >= '0') && (ch < '9'))) { 19 | result[j++] = ch; 20 | } 21 | else if (ch == ' ') { 22 | result[j++] = '+'; 23 | } 24 | else if (ch == '.' || ch == '-' || ch == '_' || ch == '*') { 25 | result[j++] = ch; 26 | } 27 | else { 28 | if (j + 3 < resultSize) { 29 | sprintf_s(result + j, resultSize - j, "%%%02X", (unsigned char)ch); 30 | j += 3; 31 | } 32 | else { 33 | return 0; 34 | } 35 | } 36 | } 37 | 38 | result[j] = '\0'; 39 | return j; 40 | } 41 | -------------------------------------------------------------------------------- /StringProcess/URIEncode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | int URLEncode(const char* str, const int strSize, char* result, const int resultSize); 4 | -------------------------------------------------------------------------------- /cJSON/cJSON.c: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS 2 | /* 3 | Copyright (c) 2009 Dave Gamble 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | 24 | /* cJSON */ 25 | /* JSON parser in C. */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include "cJSON.h" 35 | 36 | static const char *ep; 37 | 38 | const char *cJSON_GetErrorPtr(void) {return ep;} 39 | 40 | static int cJSON_strcasecmp(const char *s1,const char *s2) 41 | { 42 | if (!s1) return (s1==s2)?0:1;if (!s2) return 1; 43 | for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0; 44 | return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2); 45 | } 46 | 47 | static void *(__cdecl * cJSON_malloc)(size_t sz) = malloc; 48 | static void (__cdecl * cJSON_free)(void *ptr) = free; 49 | 50 | static char* cJSON_strdup(const char* str) 51 | { 52 | size_t len; 53 | char* copy; 54 | 55 | len = strlen(str) + 1; 56 | if (!(copy = (char*)cJSON_malloc(len))) return 0; 57 | memcpy(copy,str,len); 58 | return copy; 59 | } 60 | 61 | void cJSON_InitHooks(cJSON_Hooks* hooks) 62 | { 63 | if (!hooks) { /* Reset hooks */ 64 | cJSON_malloc = malloc; 65 | cJSON_free = free; 66 | return; 67 | } 68 | 69 | cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; 70 | cJSON_free = (hooks->free_fn)?hooks->free_fn:free; 71 | } 72 | 73 | /* Internal constructor. */ 74 | static cJSON *cJSON_New_Item(void) 75 | { 76 | cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); 77 | if (node) memset(node,0,sizeof(cJSON)); 78 | return node; 79 | } 80 | 81 | /* Delete a cJSON structure. */ 82 | void cJSON_Delete(cJSON *c) 83 | { 84 | cJSON *next; 85 | while (c) 86 | { 87 | next=c->next; 88 | if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child); 89 | if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); 90 | if (!(c->type&cJSON_StringIsConst) && c->string) cJSON_free(c->string); 91 | cJSON_free(c); 92 | c=next; 93 | } 94 | } 95 | 96 | /* Parse the input text to generate a number, and populate the result into item. */ 97 | static const char *parse_number(cJSON *item,const char *num) 98 | { 99 | double n=0,sign=1,scale=0;int subscale=0,signsubscale=1; 100 | 101 | if (*num=='-') sign=-1,num++; /* Has sign? */ 102 | if (*num=='0') num++; /* is zero */ 103 | if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */ 104 | if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */ 105 | if (*num=='e' || *num=='E') /* Exponent? */ 106 | { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */ 107 | while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */ 108 | } 109 | 110 | n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */ 111 | 112 | item->valuedouble=n; 113 | item->valueint=(int)n; 114 | item->type=cJSON_Number; 115 | return num; 116 | } 117 | 118 | static int pow2gt (int x) { --x; x|=x>>1; x|=x>>2; x|=x>>4; x|=x>>8; x|=x>>16; return x+1; } 119 | 120 | typedef struct {char *buffer; int length; int offset; } printbuffer; 121 | 122 | static char* ensure(printbuffer *p,int needed) 123 | { 124 | char *newbuffer;int newsize; 125 | if (!p || !p->buffer) return 0; 126 | needed+=p->offset; 127 | if (needed<=p->length) return p->buffer+p->offset; 128 | 129 | newsize=pow2gt(needed); 130 | newbuffer=(char*)cJSON_malloc(newsize); 131 | if (!newbuffer) {cJSON_free(p->buffer);p->length=0,p->buffer=0;return 0;} 132 | if (newbuffer) memcpy(newbuffer,p->buffer,p->length); 133 | cJSON_free(p->buffer); 134 | p->length=newsize; 135 | p->buffer=newbuffer; 136 | return newbuffer+p->offset; 137 | } 138 | 139 | static int update(printbuffer *p) 140 | { 141 | char *str; 142 | if (!p || !p->buffer) return 0; 143 | str=p->buffer+p->offset; 144 | return p->offset+strlen(str); 145 | } 146 | 147 | /* Render the number nicely from the given item into a string. */ 148 | static char *print_number(cJSON *item,printbuffer *p) 149 | { 150 | char *str=0; 151 | double d=item->valuedouble; 152 | if (d==0) 153 | { 154 | if (p) str=ensure(p,2); 155 | else str=(char*)cJSON_malloc(2); /* special case for 0. */ 156 | if (str) strcpy(str,"0"); 157 | } 158 | else if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) 159 | { 160 | if (p) str=ensure(p,21); 161 | else str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */ 162 | if (str) sprintf(str,"%d",item->valueint); 163 | } 164 | else 165 | { 166 | if (p) str=ensure(p,64); 167 | else str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */ 168 | if (str) 169 | { 170 | if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d); 171 | else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d); 172 | else sprintf(str,"%f",d); 173 | } 174 | } 175 | return str; 176 | } 177 | 178 | static unsigned parse_hex4(const char *str) 179 | { 180 | unsigned h=0; 181 | 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; 182 | h=h<<4;str++; 183 | 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; 184 | h=h<<4;str++; 185 | 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; 186 | h=h<<4;str++; 187 | 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; 188 | return h; 189 | } 190 | 191 | /* Parse the input text into an unescaped cstring, and populate item. */ 192 | static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; 193 | static const char *parse_string(cJSON *item,const char *str) 194 | { 195 | const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2; 196 | if (*str!='\"') {ep=str;return 0;} /* not a string! */ 197 | 198 | while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */ 199 | 200 | out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */ 201 | if (!out) return 0; 202 | 203 | ptr=str+1;ptr2=out; 204 | while (*ptr!='\"' && *ptr) 205 | { 206 | if (*ptr!='\\') *ptr2++=*ptr++; 207 | else 208 | { 209 | ptr++; 210 | switch (*ptr) 211 | { 212 | case 'b': *ptr2++='\b'; break; 213 | case 'f': *ptr2++='\f'; break; 214 | case 'n': *ptr2++='\n'; break; 215 | case 'r': *ptr2++='\r'; break; 216 | case 't': *ptr2++='\t'; break; 217 | case 'u': /* transcode utf16 to utf8. */ 218 | uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */ 219 | 220 | if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */ 221 | 222 | if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */ 223 | { 224 | if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */ 225 | uc2=parse_hex4(ptr+3);ptr+=6; 226 | if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */ 227 | uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF)); 228 | } 229 | 230 | len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len; 231 | 232 | switch (len) { 233 | case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; 234 | case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; 235 | case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; 236 | case 1: *--ptr2 =(uc | firstByteMark[len]); 237 | } 238 | ptr2+=len; 239 | break; 240 | default: *ptr2++=*ptr; break; 241 | } 242 | ptr++; 243 | } 244 | } 245 | *ptr2=0; 246 | if (*ptr=='\"') ptr++; 247 | item->valuestring=out; 248 | item->type=cJSON_String; 249 | return ptr; 250 | } 251 | 252 | 253 | static int escapable[256]={ 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 254 | 0,0,1,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 255 | 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,0,0,0, 256 | 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 257 | 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 258 | 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 259 | 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 260 | 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}; 261 | 262 | /* Render the cstring provided to an escaped version that can be printed. */ 263 | static char *print_string_ptr(const char *str,printbuffer *p) 264 | { 265 | const char *ptr;char *ptr2,*out;int len=0,flag=0;unsigned char token; 266 | 267 | ptr=str;while (*ptr) flag|=escapable[*ptr++]; 268 | if (!flag) 269 | { 270 | len=ptr-str; 271 | if (p) out=ensure(p,len+3); 272 | else out=(char*)cJSON_malloc(len+3); 273 | if (!out) return 0; 274 | ptr2=out;*ptr2++='\"'; 275 | strcpy(ptr2,str); 276 | ptr2[len]='\"'; 277 | ptr2[len+1]=0; 278 | return out; 279 | } 280 | 281 | if (!str) 282 | { 283 | if (p) out=ensure(p,3); 284 | else out=(char*)cJSON_malloc(3); 285 | if (!out) return 0; 286 | strcpy(out,"\"\""); 287 | return out; 288 | } 289 | ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;} 290 | 291 | if (p) out=ensure(p,len+3); 292 | else out=(char*)cJSON_malloc(len+3); 293 | if (!out) return 0; 294 | 295 | ptr2=out;ptr=str; 296 | *ptr2++='\"'; 297 | while (*ptr) 298 | { 299 | if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; 300 | else 301 | { 302 | *ptr2++='\\'; 303 | switch (token=*ptr++) 304 | { 305 | case '\\': *ptr2++='\\'; break; 306 | case '\"': *ptr2++='\"'; break; 307 | case '\b': *ptr2++='b'; break; 308 | case '\f': *ptr2++='f'; break; 309 | case '\n': *ptr2++='n'; break; 310 | case '\r': *ptr2++='r'; break; 311 | case '\t': *ptr2++='t'; break; 312 | default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */ 313 | } 314 | } 315 | } 316 | *ptr2++='\"';*ptr2++=0; 317 | return out; 318 | } 319 | /* Invote print_string_ptr (which is useful) on an item. */ 320 | static char *print_string(cJSON *item,printbuffer *p) {return print_string_ptr(item->valuestring,p);} 321 | 322 | /* Predeclare these prototypes. */ 323 | static const char *parse_value(cJSON *item,const char *value); 324 | static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p); 325 | static const char *parse_array(cJSON *item,const char *value); 326 | static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p); 327 | static const char *parse_object(cJSON *item,const char *value); 328 | static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p); 329 | 330 | /* Utility to jump whitespace and cr/lf */ 331 | static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;} 332 | 333 | /* Parse an object - create a new root, and populate. */ 334 | cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated) 335 | { 336 | const char *end=0; 337 | cJSON *c=cJSON_New_Item(); 338 | ep=0; 339 | if (!c) return 0; /* memory fail */ 340 | 341 | end=parse_value(c,skip(value)); 342 | if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */ 343 | 344 | /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ 345 | if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}} 346 | if (return_parse_end) *return_parse_end=end; 347 | return c; 348 | } 349 | /* Default options for cJSON_Parse */ 350 | cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);} 351 | 352 | /* Render a cJSON item/entity/structure to text. */ 353 | char *cJSON_Print(cJSON *item) {return print_value(item,0,1,0);} 354 | char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0,0);} 355 | 356 | char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt) 357 | { 358 | printbuffer p; 359 | p.buffer=(char*)cJSON_malloc(prebuffer); 360 | p.length=prebuffer; 361 | p.offset=0; 362 | return print_value(item,0,fmt,&p); 363 | return p.buffer; 364 | } 365 | 366 | 367 | /* Parser core - when encountering text, process appropriately. */ 368 | static const char *parse_value(cJSON *item,const char *value) 369 | { 370 | if (!value) return 0; /* Fail on null. */ 371 | if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; } 372 | if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; } 373 | if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; } 374 | if (*value=='\"') { return parse_string(item,value); } 375 | if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); } 376 | if (*value=='[') { return parse_array(item,value); } 377 | if (*value=='{') { return parse_object(item,value); } 378 | 379 | ep=value;return 0; /* failure. */ 380 | } 381 | 382 | /* Render a value to text. */ 383 | static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p) 384 | { 385 | char *out=0; 386 | if (!item) return 0; 387 | if (p) 388 | { 389 | switch ((item->type)&255) 390 | { 391 | case cJSON_NULL: {out=ensure(p,5); if (out) strcpy(out,"null"); break;} 392 | case cJSON_False: {out=ensure(p,6); if (out) strcpy(out,"false"); break;} 393 | case cJSON_True: {out=ensure(p,5); if (out) strcpy(out,"true"); break;} 394 | case cJSON_Number: out=print_number(item,p);break; 395 | case cJSON_String: out=print_string(item,p);break; 396 | case cJSON_Array: out=print_array(item,depth,fmt,p);break; 397 | case cJSON_Object: out=print_object(item,depth,fmt,p);break; 398 | } 399 | } 400 | else 401 | { 402 | switch ((item->type)&255) 403 | { 404 | case cJSON_NULL: out=cJSON_strdup("null"); break; 405 | case cJSON_False: out=cJSON_strdup("false");break; 406 | case cJSON_True: out=cJSON_strdup("true"); break; 407 | case cJSON_Number: out=print_number(item,0);break; 408 | case cJSON_String: out=print_string(item,0);break; 409 | case cJSON_Array: out=print_array(item,depth,fmt,0);break; 410 | case cJSON_Object: out=print_object(item,depth,fmt,0);break; 411 | } 412 | } 413 | return out; 414 | } 415 | 416 | /* Build an array from input text. */ 417 | static const char *parse_array(cJSON *item,const char *value) 418 | { 419 | cJSON *child; 420 | if (*value!='[') {ep=value;return 0;} /* not an array! */ 421 | 422 | item->type=cJSON_Array; 423 | value=skip(value+1); 424 | if (*value==']') return value+1; /* empty array. */ 425 | 426 | item->child=child=cJSON_New_Item(); 427 | if (!item->child) return 0; /* memory fail */ 428 | value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */ 429 | if (!value) return 0; 430 | 431 | while (*value==',') 432 | { 433 | cJSON *new_item; 434 | if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ 435 | child->next=new_item;new_item->prev=child;child=new_item; 436 | value=skip(parse_value(child,skip(value+1))); 437 | if (!value) return 0; /* memory fail */ 438 | } 439 | 440 | if (*value==']') return value+1; /* end of array */ 441 | ep=value;return 0; /* malformed. */ 442 | } 443 | 444 | /* Render an array to text */ 445 | static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p) 446 | { 447 | char **entries; 448 | char *out=0,*ptr,*ret;int len=5; 449 | cJSON *child=item->child; 450 | int numentries=0,i=0,fail=0; 451 | size_t tmplen=0; 452 | 453 | /* How many entries in the array? */ 454 | while (child) numentries++,child=child->next; 455 | /* Explicitly handle numentries==0 */ 456 | if (!numentries) 457 | { 458 | if (p) out=ensure(p,3); 459 | else out=(char*)cJSON_malloc(3); 460 | if (out) strcpy(out,"[]"); 461 | return out; 462 | } 463 | 464 | if (p) 465 | { 466 | /* Compose the output array. */ 467 | i=p->offset; 468 | ptr=ensure(p,1);if (!ptr) return 0; *ptr='['; p->offset++; 469 | child=item->child; 470 | while (child && !fail) 471 | { 472 | print_value(child,depth+1,fmt,p); 473 | p->offset=update(p); 474 | 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;} 475 | child=child->next; 476 | } 477 | ptr=ensure(p,2);if (!ptr) return 0; *ptr++=']';*ptr=0; 478 | out=(p->buffer)+i; 479 | } 480 | else 481 | { 482 | /* Allocate an array to hold the values for each */ 483 | entries=(char**)cJSON_malloc(numentries*sizeof(char*)); 484 | if (!entries) return 0; 485 | memset(entries,0,numentries*sizeof(char*)); 486 | /* Retrieve all the results: */ 487 | child=item->child; 488 | while (child && !fail) 489 | { 490 | ret=print_value(child,depth+1,fmt,0); 491 | entries[i++]=ret; 492 | if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1; 493 | child=child->next; 494 | } 495 | 496 | /* If we didn't fail, try to malloc the output string */ 497 | if (!fail) out=(char*)cJSON_malloc(len); 498 | /* If that fails, we fail. */ 499 | if (!out) fail=1; 500 | 501 | /* Handle failure. */ 502 | if (fail) 503 | { 504 | for (i=0;itype=cJSON_Object; 531 | value=skip(value+1); 532 | if (*value=='}') return value+1; /* empty array. */ 533 | 534 | item->child=child=cJSON_New_Item(); 535 | if (!item->child) return 0; 536 | value=skip(parse_string(child,skip(value))); 537 | if (!value) return 0; 538 | child->string=child->valuestring;child->valuestring=0; 539 | if (*value!=':') {ep=value;return 0;} /* fail! */ 540 | value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ 541 | if (!value) return 0; 542 | 543 | while (*value==',') 544 | { 545 | cJSON *new_item; 546 | if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ 547 | child->next=new_item;new_item->prev=child;child=new_item; 548 | value=skip(parse_string(child,skip(value+1))); 549 | if (!value) return 0; 550 | child->string=child->valuestring;child->valuestring=0; 551 | if (*value!=':') {ep=value;return 0;} /* fail! */ 552 | value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ 553 | if (!value) return 0; 554 | } 555 | 556 | if (*value=='}') return value+1; /* end of array */ 557 | ep=value;return 0; /* malformed. */ 558 | } 559 | 560 | /* Render an object to text. */ 561 | static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p) 562 | { 563 | char **entries=0,**names=0; 564 | char *out=0,*ptr,*ret,*str;int len=7,i=0,j; 565 | cJSON *child=item->child; 566 | int numentries=0,fail=0; 567 | size_t tmplen=0; 568 | /* Count the number of entries. */ 569 | while (child) numentries++,child=child->next; 570 | /* Explicitly handle empty object case */ 571 | if (!numentries) 572 | { 573 | if (p) out=ensure(p,fmt?depth+4:3); 574 | else out=(char*)cJSON_malloc(fmt?depth+4:3); 575 | if (!out) return 0; 576 | ptr=out;*ptr++='{'; 577 | if (fmt) {*ptr++='\n';for (i=0;ioffset; 585 | len=fmt?2:1; ptr=ensure(p,len+1); if (!ptr) return 0; 586 | *ptr++='{'; if (fmt) *ptr++='\n'; *ptr=0; p->offset+=len; 587 | child=item->child;depth++; 588 | while (child) 589 | { 590 | if (fmt) 591 | { 592 | ptr=ensure(p,depth); if (!ptr) return 0; 593 | for (j=0;joffset+=depth; 595 | } 596 | print_string_ptr(child->string,p); 597 | p->offset=update(p); 598 | 599 | len=fmt?2:1; 600 | ptr=ensure(p,len); if (!ptr) return 0; 601 | *ptr++=':';if (fmt) *ptr++='\t'; 602 | p->offset+=len; 603 | 604 | print_value(child,depth,fmt,p); 605 | p->offset=update(p); 606 | 607 | len=(fmt?1:0)+(child->next?1:0); 608 | ptr=ensure(p,len+1); if (!ptr) return 0; 609 | if (child->next) *ptr++=','; 610 | if (fmt) *ptr++='\n';*ptr=0; 611 | p->offset+=len; 612 | child=child->next; 613 | } 614 | ptr=ensure(p,fmt?(depth+1):2); if (!ptr) return 0; 615 | if (fmt) for (i=0;ibuffer)+i; 618 | } 619 | else 620 | { 621 | /* Allocate space for the names and the objects */ 622 | entries=(char**)cJSON_malloc(numentries*sizeof(char*)); 623 | if (!entries) return 0; 624 | names=(char**)cJSON_malloc(numentries*sizeof(char*)); 625 | if (!names) {cJSON_free(entries);return 0;} 626 | memset(entries,0,sizeof(char*)*numentries); 627 | memset(names,0,sizeof(char*)*numentries); 628 | 629 | /* Collect all the results into our arrays: */ 630 | child=item->child;depth++;if (fmt) len+=depth; 631 | while (child) 632 | { 633 | names[i]=str=print_string_ptr(child->string,0); 634 | entries[i++]=ret=print_value(child,depth,fmt,0); 635 | if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1; 636 | child=child->next; 637 | } 638 | 639 | /* Try to allocate the output string */ 640 | if (!fail) out=(char*)cJSON_malloc(len); 641 | if (!out) fail=1; 642 | 643 | /* Handle failure */ 644 | if (fail) 645 | { 646 | for (i=0;ichild;int i=0;while(c)i++,c=c->next;return i;} 673 | cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;} 674 | cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} 675 | 676 | /* Utility for array list handling. */ 677 | static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;} 678 | /* Utility for handling references. */ 679 | 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;} 680 | 681 | /* Add item to array/object. */ 682 | 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);}} 683 | 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);} 684 | 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);} 685 | void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));} 686 | void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));} 687 | 688 | cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0; 689 | 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;} 690 | void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));} 691 | 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;} 692 | void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));} 693 | 694 | /* Replace array/object items with new ones. */ 695 | void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return; 696 | newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem; 697 | if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);} 698 | 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);}} 699 | 700 | /* Create basic types: */ 701 | cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;} 702 | cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;} 703 | cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;} 704 | cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;} 705 | 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;} 706 | cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;} 707 | cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;} 708 | cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} 709 | 710 | /* Create Arrays: */ 711 | 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;} 712 | 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;} 713 | 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;} 714 | 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;} 715 | 716 | /* Duplication */ 717 | cJSON *cJSON_Duplicate(cJSON *item,int recurse) 718 | { 719 | cJSON *newitem,*cptr,*nptr=0,*newchild; 720 | /* Bail on bad ptr */ 721 | if (!item) return 0; 722 | /* Create new item */ 723 | newitem=cJSON_New_Item(); 724 | if (!newitem) return 0; 725 | /* Copy over all vars */ 726 | newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble; 727 | if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}} 728 | if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}} 729 | /* If non-recursive, then we're done! */ 730 | if (!recurse) return newitem; 731 | /* Walk the ->next chain for the child. */ 732 | cptr=item->child; 733 | while (cptr) 734 | { 735 | newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */ 736 | if (!newchild) {cJSON_Delete(newitem);return 0;} 737 | if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */ 738 | else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */ 739 | cptr=cptr->next; 740 | } 741 | return newitem; 742 | } 743 | 744 | void cJSON_Minify(char *json) 745 | { 746 | char *into=json; 747 | while (*json) 748 | { 749 | if (*json==' ') json++; 750 | else if (*json=='\t') json++; // Whitespace characters. 751 | else if (*json=='\r') json++; 752 | else if (*json=='\n') json++; 753 | else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line. 754 | else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments. 755 | else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive. 756 | else *into++=*json++; // All other characters. 757 | } 758 | *into=0; // and null-terminate. 759 | } 760 | #undef _CRT_SECURE_NO_WARNINGS -------------------------------------------------------------------------------- /cJSON/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 *(__cdecl* malloc_fn)(size_t sz); 59 | void (__cdecl* 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_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem); 119 | extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); 120 | 121 | /* Duplicate a cJSON item */ 122 | extern cJSON *cJSON_Duplicate(cJSON *item,int recurse); 123 | /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will 124 | need to be released. With recurse!=0, it will duplicate any children connected to the item. 125 | The item->next and ->prev pointers are always zero on return from Duplicate. */ 126 | 127 | /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ 128 | extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated); 129 | 130 | extern void cJSON_Minify(char *json); 131 | 132 | /* Macros for creating things quickly. */ 133 | #define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) 134 | #define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) 135 | #define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) 136 | #define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) 137 | #define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) 138 | #define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) 139 | 140 | /* When assigning an integer value, it needs to be propagated to valuedouble too. */ 141 | #define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val)) 142 | 143 | #ifdef __cplusplus 144 | } 145 | #endif 146 | 147 | #endif 148 | -------------------------------------------------------------------------------- /cJSON/cJSON.vcxitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | {19899d8b-f0bb-4afa-b671-1ccb10c98aa5} 7 | 8 | 9 | 10 | %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | --------------------------------------------------------------------------------