├── .gitattributes ├── .gitignore └── BaiduOldDriver ├── API.md ├── BaiduOldDriver.sln ├── Client ├── App.config ├── Client.csproj ├── LoginForm.Designer.cs ├── LoginForm.cs ├── LoginForm.resx ├── MainForm.Designer.cs ├── MainForm.cs ├── MainForm.resx ├── Program.cs └── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Connoisseur ├── App.config ├── Connoisseur.csproj ├── Program.cs └── Properties │ └── AssemblyInfo.cs ├── Downloader ├── Adapter.cs ├── BaiduAdapter.cs ├── Block.cs ├── DownloadSource.cs ├── Downloader.csproj ├── FileTask.cs └── Properties │ └── AssemblyInfo.cs ├── GoodSamaritan ├── App.config ├── GoodSamaritan.csproj ├── MyHttpServer.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── SimpleHttpServer.cs ├── NetDisk ├── Authentication.cs ├── CRC32.cs ├── CookieAwareWebClient.cs ├── Credential.cs ├── Extension.cs ├── NetDisk.csproj ├── Operation.cs ├── PatientWebClient.cs ├── Properties │ └── AssemblyInfo.cs ├── Result.cs └── UploadHelper.cs ├── Newtonsoft.Json.dll ├── Test ├── App.config ├── Properties │ └── AssemblyInfo.cs ├── Test.cs └── Test.csproj └── login_errno.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | *.VC.VC.opendb 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 149 | # checkin your Azure Web App publish settings, but sensitive information contained 150 | # in these scripts will be unencrypted 151 | PublishScripts/ 152 | 153 | # NuGet Packages 154 | *.nupkg 155 | # The packages folder can be ignored because of Package Restore 156 | **/packages/* 157 | # except build/, which is used as an MSBuild target. 158 | !**/packages/build/ 159 | # Uncomment if necessary however generally it will be regenerated when needed 160 | #!**/packages/repositories.config 161 | # NuGet v3's project.json files produces more ignoreable files 162 | *.nuget.props 163 | *.nuget.targets 164 | 165 | # Microsoft Azure Build Output 166 | csx/ 167 | *.build.csdef 168 | 169 | # Microsoft Azure Emulator 170 | ecf/ 171 | rcf/ 172 | 173 | # Windows Store app package directories and files 174 | AppPackages/ 175 | BundleArtifacts/ 176 | Package.StoreAssociation.xml 177 | _pkginfo.txt 178 | 179 | # Visual Studio cache files 180 | # files ending in .cache can be ignored 181 | *.[Cc]ache 182 | # but keep track of directories ending in .cache 183 | !*.[Cc]ache/ 184 | 185 | # Others 186 | ClientBin/ 187 | ~$* 188 | *~ 189 | *.dbmdl 190 | *.dbproj.schemaview 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # Since there are multiple workflows, uncomment next line to ignore bower_components 197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 198 | #bower_components/ 199 | 200 | # RIA/Silverlight projects 201 | Generated_Code/ 202 | 203 | # Backup & report files from converting an old project file 204 | # to a newer Visual Studio version. Backup files are not needed, 205 | # because we have git ;-) 206 | _UpgradeReport_Files/ 207 | Backup*/ 208 | UpgradeLog*.XML 209 | UpgradeLog*.htm 210 | 211 | # SQL Server files 212 | *.mdf 213 | *.ldf 214 | 215 | # Business Intelligence projects 216 | *.rdl.data 217 | *.bim.layout 218 | *.bim_*.settings 219 | 220 | # Microsoft Fakes 221 | FakesAssemblies/ 222 | 223 | # GhostDoc plugin setting file 224 | *.GhostDoc.xml 225 | 226 | # Node.js Tools for Visual Studio 227 | .ntvs_analysis.dat 228 | 229 | # Visual Studio 6 build log 230 | *.plg 231 | 232 | # Visual Studio 6 workspace options file 233 | *.opt 234 | 235 | # Visual Studio LightSwitch build output 236 | **/*.HTMLClient/GeneratedArtifacts 237 | **/*.DesktopClient/GeneratedArtifacts 238 | **/*.DesktopClient/ModelManifest.xml 239 | **/*.Server/GeneratedArtifacts 240 | **/*.Server/ModelManifest.xml 241 | _Pvt_Extensions 242 | 243 | # Paket dependency manager 244 | .paket/paket.exe 245 | paket-files/ 246 | 247 | # FAKE - F# Make 248 | .fake/ 249 | 250 | # JetBrains Rider 251 | .idea/ 252 | *.sln.iml 253 | 254 | # ========================= 255 | # Operating System Files 256 | # ========================= 257 | 258 | # OSX 259 | # ========================= 260 | 261 | .DS_Store 262 | .AppleDouble 263 | .LSOverride 264 | 265 | # Thumbnails 266 | ._* 267 | 268 | # Files that might appear in the root of a volume 269 | .DocumentRevisions-V100 270 | .fseventsd 271 | .Spotlight-V100 272 | .TemporaryItems 273 | .Trashes 274 | .VolumeIcon.icns 275 | 276 | # Directories potentially created on remote AFP share 277 | .AppleDB 278 | .AppleDesktop 279 | Network Trash Folder 280 | Temporary Items 281 | .apdisk 282 | 283 | # Windows 284 | # ========================= 285 | 286 | # Windows image file caches 287 | Thumbs.db 288 | ehthumbs.db 289 | 290 | # Folder config file 291 | Desktop.ini 292 | 293 | # Recycle Bin used on file shares 294 | $RECYCLE.BIN/ 295 | 296 | # Windows Installer files 297 | *.cab 298 | *.msi 299 | *.msm 300 | *.msp 301 | 302 | # Windows shortcuts 303 | *.lnk 304 | -------------------------------------------------------------------------------- /BaiduOldDriver/API.md: -------------------------------------------------------------------------------- 1 | # API 概述 2 | 3 | NetDisk 是实现百度网盘 API 的 C# 工程。使用者可以直接引用编译好的 NetDisk.dll。 4 | 5 | 目前版本的目标框架是 .NET Framework 4.5,引用它的工程最好也选用 .NET 4.5。 6 | 7 | 库中几乎所有函数的返回值以 Result 为基类。约定 bool success 表示是否成功完成调用流程(但不意味着结果为成功)。如果 success = false,Exception exception 保存了相关的异常。 8 | 9 | *很多情况下,返回对象中给出的的 errno 记录了百度返回的操作结果,errno = 0 表示操作实际成功。* 10 | 11 | 网络传输使用 WebClient,它绝大多数情况下能自动选择合适的网络和(如果设置了的)代理服务器。 12 | 13 | 解决方案 BaiduOldDrive 中有若干使用 NetDisk 库的示例程序,可供参考。 14 | 15 | # 身份验证 16 | 17 | 调用 Operations 类当中的操作之前,先要用这个类当中的函数获得登录信息。请将最终得到的 Credential 对象传入此后的操作函数。 18 | 19 | 它通过模拟网页版百度网盘的登录,获得 baiduid、bduss、stoken 这三个必需的 Cookies。 20 | 21 | 下面是命令行登录流程的例子: 22 | 23 | ```cs 24 | var checkResult = Authentication.LoginCheck("用户名"); 25 | CheckSuccess(checkResult); 26 | if (checkResult.needVCode) 27 | { 28 | File.WriteAllBytes("vcode.png", checkResult.image); 29 | Console.WriteLine("输入 vcode.png 中的验证码:"); 30 | checkResult.verifyCode = Console.ReadLine(); 31 | } 32 | var loginResult = Authentication.Login("用户名", "密码", checkResult); 33 | CheckSuccess(loginResult); 34 | var credential = loginResult.credential; 35 | // credential 变量以后操作使用 36 | ``` 37 | 38 | 对于有 GUI 的程序,建议在用户名框更改时,就检查是否需要验证码,并对应显示。 39 | 40 | ## 登录检查 41 | 42 | ```cs 43 | Authentication.LoginCheck(string username) : LoginCheckResult 44 | ``` 45 | 46 | 在实际登录之前,需要先用这个函数,检查一下是否需要输入验证码。 47 | 48 | ### 参数 49 | 50 | string username: 用户名 51 | 52 | ### 返回值 53 | 54 | bool needVCode: 是否需要输入验证码 55 | 56 | byte[] image: 如果需要验证码,这个数组存储了验证码图片 57 | 58 | ## 登录 59 | 60 | ```cs 61 | Authentication.Login(string username, string password, LoginCheckResult checkResult) : LoginResult 62 | ``` 63 | 64 | 对于同一个用户名,在调用 LoginCheck后,实际进行登录。如果 checkResult.needVCode == true,需将验证码文字存入 checkResult.verifyCode。 65 | 66 | ### 参数 67 | 68 | string username: 用户名 69 | 70 | string password: 密码 71 | 72 | LoginCheckResult checkResult: 该用户名对应的 LoginCheck 返回结果 73 | 74 | ### 返回值 75 | 76 | Credential credential: 表示登录用户的身份信息 77 | 78 | int errno: 错误代码,详见 [这里](https://github.com/tiancaihb/BaiduOldDriver/blob/master/BaiduOldDriver/login_errno.txt) 79 | 80 | ## 检查身份信息是否有效 81 | 82 | ```cs 83 | Authentication.IsLoggedIn(Credential credential) : bool 84 | ``` 85 | 86 | ### 参数 87 | 88 | Credential credential: 要检查的身份信息 89 | 90 | ### 返回值 91 | 92 | 是或否 93 | 94 | # 获取基本信息 95 | 96 | ## 获取配额 97 | 98 | ```cs 99 | Operation.GetQuota(Credential credential) : QuotaResult 100 | ``` 101 | 102 | ### 参数 103 | 104 | Credential credential: 身份信息 105 | 106 | ### 返回值 107 | 108 | int errno: 错误代码 109 | 110 | long total: 总字节数 111 | 112 | long free: 空余字节数 113 | 114 | long used: 使用字节数 115 | 116 | ## 获取用户信息 117 | 118 | ```cs 119 | Operation.GetUserInfo(Credential credential) : UserInfoResult 120 | ``` 121 | 122 | ### 参数 123 | 124 | Credential credential: 身份信息 125 | 126 | ### 返回值 127 | 128 | int errno: 错误代码 129 | 130 | string records[0].avatar_url: 头像图片的地址 131 | 132 | string records[0].uname: 用户昵称 133 | 134 | string records[0].priority_name: 带星号的用户昵称 135 | 136 | # 文件操作 137 | 138 | ## 获取文件列表 139 | 140 | ```cs 141 | Operation.GetFileList(string path, Credential credential) : FileListResult 142 | ``` 143 | 144 | 对于文件夹 path,列出其下所有的文件和文件夹。根目录是“/”,其他路径后不加斜线,例如“/Folder”。 145 | 146 | ### 参数 147 | 148 | string path: 网盘上的文件夹全路径 149 | 150 | Credential credential: 身份信息 151 | 152 | ### 返回值 153 | 154 | int errno: 错误代码 155 | 156 | FileListResult.Entry[] list: 文件(夹)信息的数组 157 | 158 | int list.isdir: 是否为文件夹(1 或 0) 159 | 160 | string list.path: 该项目的全路径 161 | 162 | string list.server_filename: 该项目的名称 163 | 164 | long list.size: 字节数 165 | 166 | ## 获得缩略图 167 | 168 | ```cs 169 | Operation.GetThumbnail(string path, Credential credential, int width = 125, int height = 90, int quality = 100) : ThumbnailResult 170 | ``` 171 | 172 | ### 参数 173 | 174 | string path: 网盘上的文件全路径 175 | 176 | Credential credential: 身份信息 177 | 178 | int width: 宽度 179 | 180 | int height: 高度 181 | 182 | int quality: 质量 183 | 184 | ### 返回值 185 | 186 | byte[] image: 缩略图文件 187 | 188 | ## 复制 / 移动 189 | 190 | ```cs 191 | Operation.Copy(string path, string dest, string newname, Credential credential) : FileOperationResult 192 | Operation.Move(string path, string dest, string newname, Credential credential) : FileOperationResult 193 | ``` 194 | 195 | 如果指定的名字已经存在,会返回错误。 196 | 197 | ### 参数 198 | 199 | string path: 网盘上的文件(夹)全路径 200 | 201 | string dest: 目标所在文件夹的全路径 202 | 203 | string newname: 新的名字 204 | 205 | Credential credential: 身份信息 206 | 207 | ### 返回值 208 | 209 | int errno: 错误代码 210 | 211 | string path: 原文件(夹)的全路径 212 | 213 | ## 重命名 214 | 215 | ```cs 216 | Operation.Rename(string path, string newname, Credential credential) : FileOperationResult 217 | ``` 218 | 219 | 如果指定的名字已经存在,会返回错误。 220 | 221 | ### 参数 222 | 223 | string path: 网盘上的文件(夹)全路径 224 | 225 | string newname: 新的名字 226 | 227 | Credential credential: 身份信息 228 | 229 | ### 返回值 230 | 231 | int errno: 错误代码 232 | 233 | string path: 原文件(夹)的全路径 234 | 235 | ## 删除 236 | 237 | ```cs 238 | Operation.Delete(string path, Credential credential) : FileOperationResult 239 | ``` 240 | 241 | ### 参数 242 | 243 | string path: 网盘上的文件(夹)全路径 244 | 245 | Credential credential: 身份信息 246 | 247 | ### 返回值 248 | 249 | int errno: 错误代码 250 | 251 | string path: 原文件(夹)的全路径 252 | 253 | ## 新建文件夹 254 | 255 | ```cs 256 | Operation.CreateFolder(string path, Credential credential) : FileOperationResult 257 | ``` 258 | 259 | 如果指定的名字已经存在,会自动改名,例如"/Folder(1)"。可以同时新建若干级文件夹。 260 | 261 | ### 参数 262 | 263 | string path: 网盘上的文件夹全路径 264 | 265 | Credential credential: 身份信息 266 | 267 | ### 返回值 268 | 269 | int errno: 错误代码 270 | 271 | string path: 实际创建的文件夹全路径 272 | 273 | # 上传下载 274 | 275 | ## 获取下载地址 276 | 277 | ```cs 278 | Operation.GetDownload(string path, Credential credential) : GetDownloadResult 279 | ``` 280 | 281 | 对于一个文件通常会返回一组地址,从域名可以看出是不同地区的服务器。下载速度有时差别会很大,特别是从国外下载的时候;此外返回的 rank 不一定符合实际情况。这些地址的有效期是 8 小时。 282 | 283 | 百度网盘客户端对于非会员有某种限速,但给会员的下载地址可能也会比非会员的更快。具体情况还需进一步实验。 284 | 285 | ### 参数 286 | 287 | string path: 网盘上的文件夹全路径 288 | 289 | Credential credential: 身份信息 290 | 291 | ### 返回值 292 | 293 | GetDownloadResult.Entry[] urls: 下载地址的数组 294 | 295 | int urls.rank: 百度给的服务器优先度排名 296 | 297 | string urls.url: 下载地址 298 | 299 | ## 简单上传 300 | 301 | ```cs 302 | Operation.SimpleUpload(string localpath, string remotepath, Credential credential, string host = "c.pcs.baidu.com") : CommitUploadResult 303 | ``` 304 | 305 | 适合小文件上传。因为实现当中会先把文件全部读入内存,并且一次 WebClient 操作的超时有限,对于较大(例如 >= 10MB)的文件,请考虑分块上传。 306 | 307 | 目前这个函数仍然是通过分块上传实现的。 308 | 309 | ### 参数 310 | 311 | string localpath: 本地文件全路径 312 | 313 | string remotepath: 网盘上的文件保存路径 314 | 315 | Credential credential: 身份信息 316 | 317 | string host: 上传服务器的地址,可以用 GetUploadServers 函数获取 318 | 319 | ### 返回值 320 | 321 | int errno: 错误代码 322 | 323 | 其他成员类似 FileListResult.Entry 324 | 325 | ## 分块上传(简化版) 326 | 327 | ```cs 328 | Operation.ChunkedUpload(string localpath, string remotepath, Credential credential) : CommitUploadResult 329 | ``` 330 | 331 | 在内部使用 4MB 大小的分块上传指定文件。该函数会自动获取并选择第一个上传服务器。 332 | 333 | ### 参数 334 | 335 | string localpath: 本地文件全路径 336 | 337 | string remotepath: 网盘上的文件保存路径 338 | 339 | Credential credential: 身份信息 340 | 341 | ### 返回值 342 | 343 | int errno: 错误代码 344 | 345 | 其他成员类似 FileListResult.Entry 346 | 347 | ## 上传准备:获取文件哈希值 348 | 349 | ```cs 350 | UploadHelper.GetFileProperty(string path) : FileProperty 351 | ``` 352 | 353 | 在使用其他上传函数之前,需要先调用此函数,计算分块和秒传所需的分块哈希值等信息。 354 | 355 | ### 参数 356 | 357 | string path: 本地文件全路径 358 | 359 | ### 返回值 360 | 361 | 记录文件哈希值的对象 362 | 363 | ## 极速秒传 364 | 365 | ```cs 366 | Operation.RapidUpload(FileProperty prop, string path, Credential credential) : RapidUploadResult 367 | ``` 368 | 369 | 通过提供文件的 MD5、CRC32、开头的 MD5、每个分块的 MD5,由服务器查询是否已经有此文件,从而实现“极速秒传”。失败则 errno = 404。 370 | 371 | ### 参数 372 | 373 | FileProperty prop: 文件的哈希值信息 374 | 375 | string path: 网盘上的文件保存路径 376 | 377 | Credential credential: 身份信息 378 | 379 | ### 返回值 380 | 381 | int errno: 错误代码 382 | 383 | FileListResult.Entry info: 若成功上传,该文件的信息 384 | 385 | ## 初始化分块上传 386 | 387 | ```cs 388 | Operation.InitUpload(FileProperty prop, string path, Credential credential) : InitUploadResult 389 | ``` 390 | 391 | 在计算好一个文件的哈希信息后,文件的分块上传分为三个步骤:初始化,上传每个分块,以及提交。首先,调用此函数,上传文件的分块信息以及获得上传会话 ID。有可能服务器上已经有某些分块了,所以 block_list 不包括所有分块的编号。 392 | 393 | 使用方法可以参见 Operation.ChunkedUpload 的实现。 394 | 395 | ### 参数 396 | 397 | FileProperty prop: 文件的哈希值信息 398 | 399 | string path: 网盘上的文件保存路径 400 | 401 | Credential credential: 身份信息 402 | 403 | ### 返回值 404 | 405 | int errno: 错误代码 406 | 407 | string uploadid: 上传会话的 ID 408 | 409 | int[] block_list: 需要上传的分块编号 410 | 411 | ## 上传分块内容 412 | 413 | ```cs 414 | Operation.UploadBlock(FileProperty prop, string path, InitUploadResult session, FileStream stream, int blockid, string host, Credential credential) 415 | ``` 416 | 417 | 初始化完成后,由调用者打开一个能读取的 FileStream,这样每次上传一个分块时可以重用。 418 | 419 | ### 参数 420 | 421 | FileProperty prop: 文件的哈希值信息 422 | 423 | string path: 网盘上的文件保存路径 424 | 425 | InitUploadResult session: 初始化得到的结果 426 | 427 | FileStream stream: 供读取的文件流 428 | 429 | int blockid: 块的序号 430 | 431 | string host: 上传服务器的地址,可以用 GetUploadServers 函数获取 432 | 433 | Credential credential: 身份信息 434 | 435 | ### 返回值 436 | 437 | 由 bool success 表示是否成功 438 | 439 | ## 提交分块上传 440 | 441 | ```cs 442 | Operation.CommitUpload(FileProperty prop, string path, InitUploadResult session, Credential credential) : CommitUploadResult 443 | ``` 444 | 445 | 上传完成所有要求的分块之后,调用此函数提交。返回新建文件的信息。如果文件名已存在,会自动重命名。 446 | 447 | ### 参数 448 | 449 | FileProperty prop: 文件的哈希值信息 450 | 451 | string path: 网盘上的文件保存路径 452 | 453 | InitUploadResult session: 初始化得到的结果 454 | 455 | Credential credential: 身份信息 456 | 457 | ### 返回值 458 | 459 | int errno: 错误代码 460 | 461 | 其他成员类似 FileListResult.Entry 462 | 463 | ## 获得上传服务器列表 464 | 465 | ```cs 466 | Operation.GetUploadServers(Credential credential) : GetUploadServersResult 467 | ``` 468 | 469 | ### 参数 470 | 471 | Credential credential: 身份信息 472 | 473 | ### 返回值 474 | 475 | string[] servers: 服务器域名列表 476 | 477 | # 分享 478 | 479 | ## 公开 / 私密分享 480 | 481 | ```cs 482 | Operation.Share(string[] pathlist, Credential credential, string pwd = null) : ShareResult 483 | ``` 484 | 485 | ### 参数 486 | 487 | string[] pathlist: 要分享的文件(夹)列表 488 | 489 | Credential credential: 身份信息 490 | 491 | string pwd: 公开分享时,传入 null;私密分享时,传入 4 个字母的字符串,包括数字或大小写字母。 492 | 493 | ### 返回值 494 | 495 | int errno: 错误代码 496 | 497 | string link: 分享链接 498 | 499 | string shorturl: 分享的短链接 500 | 501 | ## 转存他人的分享文件 502 | 503 | ```cs 504 | Operation.Transfer(string url, string path, Credential credential, string pwd = null) : TransferResult 505 | ``` 506 | 507 | ### 参数 508 | 509 | string url: 分享页的地址 510 | 511 | string path: 要保存到的文件夹 512 | 513 | Credential credential: 身份信息 514 | 515 | string pwd: 对于公开分享,传入 null;私密分享时,传入分享的密码。 516 | 517 | ### 返回值 518 | 519 | int errno: 错误代码 520 | 521 | TransferResult.Extra.Entry[] extra.list: 转存文件(夹)的信息 522 | 523 | extra.list.from: 来自分享的路径 524 | 525 | extra.list.to: 保存到的全路径 526 | 527 | # 离线下载 528 | 529 | 可以提交链接,由百度网盘下载指定的文件,保存到网盘中。如果之前已经有人下载过相同的文件,可以实现“秒传”。支持的链接有 HTTP / HTTPS、magnet、ED2K,以及 BT种子。 530 | 531 | *注意:BT 种子(.torrent 文件需要先上传到网盘当中)。* 532 | 533 | ## 获取离线下载任务列表 534 | 535 | ```cs 536 | Operation.GetOfflineList(Credential credential) : OfflineListResult 537 | ``` 538 | 539 | ### 参数 540 | 541 | Credential credential: 身份信息 542 | 543 | ### 返回值 544 | 545 | OfflineListResult.Entry[] tasks: 离线下载任务的数组 546 | 547 | long tasks.create_time: 任务创建时间 548 | 549 | string save_path: 保存到的全路径 550 | 551 | string source_url: 源地址 552 | 553 | long task_id: 下载任务的序号 554 | 555 | string task_name: 显示的任务名称 556 | 557 | long file_size: 所有文件的大小之和 558 | 559 | long finished_size: 完成下载的大小 560 | 561 | int status: 任务状态,0 表示完成,其他未知 562 | 563 | ## 查询磁力链 / BT 种子信息 564 | 565 | ```cs 566 | Operation.QueryLinkFiles(string link, Credential credential) : QueryLinkResult 567 | ``` 568 | 569 | ### 参数 570 | 571 | string link: 磁力链,或 BT 种子在网盘上的全路径 572 | 573 | Credential credential: 身份信息 574 | 575 | ### 返回值 576 | 577 | string sha1: 如果是 BT 种子,稍后需要传入这个字符串 578 | 579 | QueryLinkResult.Entry[] files: 种子中包含的文件(夹)信息 580 | 581 | string files.file_name: 文件(夹)名称 582 | 583 | long size: 文件大小 584 | 585 | ## 添加离线下载任务 586 | 587 | ```cs 588 | Operation.AddOfflineTask(string link, string savepath, Credential credential, int[] selected = null, string sha1 = "") : AddOfflineTaskResult 589 | ``` 590 | 591 | ### 参数 592 | 593 | string link: 链接,或 BT 种子在网盘上的全路径 594 | 595 | string savepath: 要保存到的文件夹 596 | 597 | Credential credential: 身份信息 598 | 599 | int[] selected: 对于磁力链或 BT 种子,选中项目在 QueryLinkFiles 返回值当中的下标,从 1 开始计数 600 | 601 | string sha1: 如果是 BT 种子,传入 QueryLinkFiles 返回值中的 sha1 602 | 603 | ### 返回值 604 | 605 | int rapid_download: 是否秒传 606 | 607 | long task_id: 任务序号 608 | 609 | ## 取消 / 删除 / 清空离线下载任务 610 | 611 | ```cs 612 | Operation.CancelOfflineTask(long taskid, Credential credential) : Result 613 | Operation.DeleteOfflineTask(long taskid, Credential credential) : Result 614 | Operation.ClearOfflineTask(Credential credential) : Result 615 | ``` 616 | 617 | 未完成的任务(status != 0)可以取消(Cancel),完成的任务可以删除(Delete)。清空列表(Clear)只删除所有已完成的离线任务。 618 | 619 | ### 参数 620 | 621 | long taskid: AddOfflineTask 返回的任务序号 622 | 623 | Credential credential: 身份信息 624 | 625 | ### 返回值 626 | 627 | 由 bool success 表示是否成功 628 | 629 | -------------------------------------------------------------------------------- /BaiduOldDriver/BaiduOldDriver.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetDisk", "NetDisk\NetDisk.csproj", "{74ECA1BF-6508-417D-BC57-DB00DAECA618}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{895C925B-58C5-42E5-B8B2-37A8EBB19823}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Downloader", "Downloader\Downloader.csproj", "{799C6C77-79D2-48EA-A56D-912EEC46B138}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GoodSamaritan", "GoodSamaritan\GoodSamaritan.csproj", "{58FA2E94-9F03-4B01-A9DE-CD585D1F1040}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Client\Client.csproj", "{19AC20F7-9932-42C5-AA0C-95B09572A55D}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Connoisseur", "Connoisseur\Connoisseur.csproj", "{830F3B0B-9F4F-4720-9F14-A25EAF37410C}" 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Release|Any CPU = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {74ECA1BF-6508-417D-BC57-DB00DAECA618}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {74ECA1BF-6508-417D-BC57-DB00DAECA618}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {74ECA1BF-6508-417D-BC57-DB00DAECA618}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {74ECA1BF-6508-417D-BC57-DB00DAECA618}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {895C925B-58C5-42E5-B8B2-37A8EBB19823}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {895C925B-58C5-42E5-B8B2-37A8EBB19823}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {895C925B-58C5-42E5-B8B2-37A8EBB19823}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {895C925B-58C5-42E5-B8B2-37A8EBB19823}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {799C6C77-79D2-48EA-A56D-912EEC46B138}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {799C6C77-79D2-48EA-A56D-912EEC46B138}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {799C6C77-79D2-48EA-A56D-912EEC46B138}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {799C6C77-79D2-48EA-A56D-912EEC46B138}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {58FA2E94-9F03-4B01-A9DE-CD585D1F1040}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {58FA2E94-9F03-4B01-A9DE-CD585D1F1040}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {58FA2E94-9F03-4B01-A9DE-CD585D1F1040}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {58FA2E94-9F03-4B01-A9DE-CD585D1F1040}.Release|Any CPU.Build.0 = Release|Any CPU 40 | {19AC20F7-9932-42C5-AA0C-95B09572A55D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {19AC20F7-9932-42C5-AA0C-95B09572A55D}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {19AC20F7-9932-42C5-AA0C-95B09572A55D}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {19AC20F7-9932-42C5-AA0C-95B09572A55D}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {830F3B0B-9F4F-4720-9F14-A25EAF37410C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {830F3B0B-9F4F-4720-9F14-A25EAF37410C}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {830F3B0B-9F4F-4720-9F14-A25EAF37410C}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {830F3B0B-9F4F-4720-9F14-A25EAF37410C}.Release|Any CPU.Build.0 = Release|Any CPU 48 | EndGlobalSection 49 | GlobalSection(SolutionProperties) = preSolution 50 | HideSolutionNode = FALSE 51 | EndGlobalSection 52 | EndGlobal 53 | -------------------------------------------------------------------------------- /BaiduOldDriver/Client/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /BaiduOldDriver/Client/Client.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {19AC20F7-9932-42C5-AA0C-95B09572A55D} 8 | WinExe 9 | Properties 10 | Client 11 | Client 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | Form 50 | 51 | 52 | LoginForm.cs 53 | 54 | 55 | Form 56 | 57 | 58 | MainForm.cs 59 | 60 | 61 | 62 | 63 | LoginForm.cs 64 | 65 | 66 | MainForm.cs 67 | 68 | 69 | ResXFileCodeGenerator 70 | Resources.Designer.cs 71 | Designer 72 | 73 | 74 | True 75 | Resources.resx 76 | 77 | 78 | SettingsSingleFileGenerator 79 | Settings.Designer.cs 80 | 81 | 82 | True 83 | Settings.settings 84 | True 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | {74eca1bf-6508-417d-bc57-db00daeca618} 93 | NetDisk 94 | 95 | 96 | 97 | 104 | -------------------------------------------------------------------------------- /BaiduOldDriver/Client/LoginForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Client 2 | { 3 | partial class LoginForm 4 | { 5 | /// 6 | /// 必需的设计器变量。 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// 清理所有正在使用的资源。 12 | /// 13 | /// 如果应释放托管资源,为 true;否则为 false。 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows 窗体设计器生成的代码 24 | 25 | /// 26 | /// 设计器支持所需的方法 - 不要修改 27 | /// 使用代码编辑器修改此方法的内容。 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.label1 = new System.Windows.Forms.Label(); 32 | this.label2 = new System.Windows.Forms.Label(); 33 | this.label3 = new System.Windows.Forms.Label(); 34 | this.textBox1 = new System.Windows.Forms.TextBox(); 35 | this.textBox2 = new System.Windows.Forms.TextBox(); 36 | this.textBox3 = new System.Windows.Forms.TextBox(); 37 | this.pictureBox1 = new System.Windows.Forms.PictureBox(); 38 | this.button1 = new System.Windows.Forms.Button(); 39 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); 40 | this.SuspendLayout(); 41 | // 42 | // label1 43 | // 44 | this.label1.AutoSize = true; 45 | this.label1.Location = new System.Drawing.Point(38, 34); 46 | this.label1.Name = "label1"; 47 | this.label1.Size = new System.Drawing.Size(73, 20); 48 | this.label1.TabIndex = 0; 49 | this.label1.Text = "用户名:"; 50 | // 51 | // label2 52 | // 53 | this.label2.AutoSize = true; 54 | this.label2.Location = new System.Drawing.Point(38, 89); 55 | this.label2.Name = "label2"; 56 | this.label2.Size = new System.Drawing.Size(57, 20); 57 | this.label2.TabIndex = 0; 58 | this.label2.Text = "密码:"; 59 | // 60 | // label3 61 | // 62 | this.label3.AutoSize = true; 63 | this.label3.Location = new System.Drawing.Point(38, 144); 64 | this.label3.Name = "label3"; 65 | this.label3.Size = new System.Drawing.Size(73, 20); 66 | this.label3.TabIndex = 0; 67 | this.label3.Text = "验证码:"; 68 | this.label3.Visible = false; 69 | // 70 | // textBox1 71 | // 72 | this.textBox1.Location = new System.Drawing.Point(126, 30); 73 | this.textBox1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 74 | this.textBox1.Name = "textBox1"; 75 | this.textBox1.Size = new System.Drawing.Size(282, 26); 76 | this.textBox1.TabIndex = 1; 77 | this.textBox1.Leave += new System.EventHandler(this.textBox1_Leave); 78 | // 79 | // textBox2 80 | // 81 | this.textBox2.Location = new System.Drawing.Point(126, 85); 82 | this.textBox2.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 83 | this.textBox2.Name = "textBox2"; 84 | this.textBox2.PasswordChar = '*'; 85 | this.textBox2.Size = new System.Drawing.Size(282, 26); 86 | this.textBox2.TabIndex = 2; 87 | // 88 | // textBox3 89 | // 90 | this.textBox3.Location = new System.Drawing.Point(126, 140); 91 | this.textBox3.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 92 | this.textBox3.Name = "textBox3"; 93 | this.textBox3.Size = new System.Drawing.Size(133, 26); 94 | this.textBox3.TabIndex = 3; 95 | this.textBox3.Visible = false; 96 | // 97 | // pictureBox1 98 | // 99 | this.pictureBox1.Location = new System.Drawing.Point(296, 132); 100 | this.pictureBox1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 101 | this.pictureBox1.Name = "pictureBox1"; 102 | this.pictureBox1.Size = new System.Drawing.Size(111, 58); 103 | this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; 104 | this.pictureBox1.TabIndex = 2; 105 | this.pictureBox1.TabStop = false; 106 | this.pictureBox1.Visible = false; 107 | this.pictureBox1.Click += new System.EventHandler(this.pictureBox1_Click); 108 | // 109 | // button1 110 | // 111 | this.button1.Location = new System.Drawing.Point(42, 206); 112 | this.button1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 113 | this.button1.Name = "button1"; 114 | this.button1.Size = new System.Drawing.Size(364, 38); 115 | this.button1.TabIndex = 4; 116 | this.button1.Text = "登录"; 117 | this.button1.UseVisualStyleBackColor = true; 118 | this.button1.Click += new System.EventHandler(this.button1_Click); 119 | // 120 | // LoginForm 121 | // 122 | this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); 123 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 124 | this.ClientSize = new System.Drawing.Size(452, 272); 125 | this.Controls.Add(this.button1); 126 | this.Controls.Add(this.pictureBox1); 127 | this.Controls.Add(this.textBox3); 128 | this.Controls.Add(this.textBox2); 129 | this.Controls.Add(this.textBox1); 130 | this.Controls.Add(this.label3); 131 | this.Controls.Add(this.label2); 132 | this.Controls.Add(this.label1); 133 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 134 | this.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 135 | this.MaximizeBox = false; 136 | this.Name = "LoginForm"; 137 | this.Text = "登录百度网盘"; 138 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); 139 | this.ResumeLayout(false); 140 | this.PerformLayout(); 141 | 142 | } 143 | 144 | #endregion 145 | 146 | private System.Windows.Forms.Label label1; 147 | private System.Windows.Forms.Label label2; 148 | private System.Windows.Forms.Label label3; 149 | private System.Windows.Forms.TextBox textBox1; 150 | private System.Windows.Forms.TextBox textBox2; 151 | private System.Windows.Forms.TextBox textBox3; 152 | private System.Windows.Forms.PictureBox pictureBox1; 153 | private System.Windows.Forms.Button button1; 154 | } 155 | } 156 | 157 | -------------------------------------------------------------------------------- /BaiduOldDriver/Client/LoginForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using NetDisk; 11 | using System.IO; 12 | 13 | namespace Client 14 | { 15 | public partial class LoginForm : Form 16 | { 17 | public LoginForm() 18 | { 19 | InitializeComponent(); 20 | } 21 | private LoginCheckResult lcr; 22 | private void textBox1_Leave(object sender, EventArgs e) 23 | { 24 | if (textBox1.Text != "") 25 | { 26 | this.Enabled = false; 27 | lcr = Authentication.LoginCheck(textBox1.Text); 28 | if (lcr.success == false) 29 | { 30 | MessageBox.Show("Error: " + lcr.exception); 31 | Application.Exit(); 32 | } 33 | label3.Visible = textBox3.Visible = pictureBox1.Visible = lcr.needVCode; 34 | textBox3.Text = ""; 35 | if (lcr.needVCode) pictureBox1.Image = ByteToImage(lcr.image); 36 | this.Enabled = true; 37 | } 38 | } 39 | private static Bitmap ByteToImage(byte[] blob) 40 | { 41 | MemoryStream mStream = new MemoryStream(); 42 | byte[] pData = blob; 43 | mStream.Write(pData, 0, Convert.ToInt32(pData.Length)); 44 | Bitmap bm = new Bitmap(mStream, false); 45 | mStream.Dispose(); 46 | return bm; 47 | } 48 | 49 | private void button1_Click(object sender, EventArgs e) 50 | { 51 | if (lcr == null) return; 52 | lcr.verifyCode = textBox3.Text; 53 | var res = Authentication.Login(textBox1.Text, textBox2.Text, lcr); 54 | if (res.success == false) 55 | { 56 | MessageBox.Show("Error: " + res.exception); 57 | textBox2.Text = ""; 58 | textBox1_Leave(null, null); 59 | return; 60 | } 61 | new MainForm(res.credential).Show(); 62 | this.Hide(); 63 | } 64 | 65 | private void pictureBox1_Click(object sender, EventArgs e) 66 | { 67 | textBox3.Text = ""; 68 | textBox1_Leave(null, null); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /BaiduOldDriver/Client/LoginForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /BaiduOldDriver/Client/MainForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Client 2 | { 3 | partial class MainForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.listView1 = new System.Windows.Forms.ListView(); 32 | this.toolStrip1 = new System.Windows.Forms.ToolStrip(); 33 | this.toolStripButton1 = new System.Windows.Forms.ToolStripButton(); 34 | this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 35 | this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 36 | this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 37 | this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel(); 38 | this.toolStrip1.SuspendLayout(); 39 | this.SuspendLayout(); 40 | // 41 | // listView1 42 | // 43 | this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { 44 | this.columnHeader1, 45 | this.columnHeader2, 46 | this.columnHeader3}); 47 | this.listView1.Dock = System.Windows.Forms.DockStyle.Fill; 48 | this.listView1.FullRowSelect = true; 49 | this.listView1.GridLines = true; 50 | this.listView1.Location = new System.Drawing.Point(0, 31); 51 | this.listView1.MultiSelect = false; 52 | this.listView1.Name = "listView1"; 53 | this.listView1.Size = new System.Drawing.Size(1263, 750); 54 | this.listView1.TabIndex = 0; 55 | this.listView1.UseCompatibleStateImageBehavior = false; 56 | this.listView1.View = System.Windows.Forms.View.Details; 57 | this.listView1.DoubleClick += new System.EventHandler(this.listView1_DoubleClick); 58 | // 59 | // toolStrip1 60 | // 61 | this.toolStrip1.ImageScalingSize = new System.Drawing.Size(24, 24); 62 | this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 63 | this.toolStripButton1, 64 | this.toolStripLabel1}); 65 | this.toolStrip1.Location = new System.Drawing.Point(0, 0); 66 | this.toolStrip1.Name = "toolStrip1"; 67 | this.toolStrip1.Size = new System.Drawing.Size(1263, 31); 68 | this.toolStrip1.TabIndex = 1; 69 | this.toolStrip1.Text = "toolStrip1"; 70 | // 71 | // toolStripButton1 72 | // 73 | this.toolStripButton1.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; 74 | this.toolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; 75 | this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta; 76 | this.toolStripButton1.Name = "toolStripButton1"; 77 | this.toolStripButton1.Size = new System.Drawing.Size(50, 28); 78 | this.toolStripButton1.Text = "刷新"; 79 | this.toolStripButton1.Click += new System.EventHandler(this.toolStripButton1_Click); 80 | // 81 | // columnHeader1 82 | // 83 | this.columnHeader1.Text = ""; 84 | this.columnHeader1.Width = 30; 85 | // 86 | // columnHeader2 87 | // 88 | this.columnHeader2.Text = "名称"; 89 | this.columnHeader2.Width = 500; 90 | // 91 | // columnHeader3 92 | // 93 | this.columnHeader3.Text = "大小"; 94 | this.columnHeader3.Width = 100; 95 | // 96 | // toolStripLabel1 97 | // 98 | this.toolStripLabel1.Name = "toolStripLabel1"; 99 | this.toolStripLabel1.Size = new System.Drawing.Size(142, 28); 100 | this.toolStripLabel1.Text = "toolStripLabel1"; 101 | // 102 | // MainForm 103 | // 104 | this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); 105 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 106 | this.ClientSize = new System.Drawing.Size(1263, 781); 107 | this.Controls.Add(this.listView1); 108 | this.Controls.Add(this.toolStrip1); 109 | this.Name = "MainForm"; 110 | this.Text = "百度网盘下载"; 111 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); 112 | this.Load += new System.EventHandler(this.MainForm_Load); 113 | this.toolStrip1.ResumeLayout(false); 114 | this.toolStrip1.PerformLayout(); 115 | this.ResumeLayout(false); 116 | this.PerformLayout(); 117 | 118 | } 119 | 120 | #endregion 121 | 122 | private System.Windows.Forms.ListView listView1; 123 | private System.Windows.Forms.ToolStrip toolStrip1; 124 | private System.Windows.Forms.ToolStripButton toolStripButton1; 125 | private System.Windows.Forms.ColumnHeader columnHeader1; 126 | private System.Windows.Forms.ColumnHeader columnHeader2; 127 | private System.Windows.Forms.ColumnHeader columnHeader3; 128 | private System.Windows.Forms.ToolStripLabel toolStripLabel1; 129 | } 130 | } -------------------------------------------------------------------------------- /BaiduOldDriver/Client/MainForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using NetDisk; 11 | using System.Net; 12 | using System.IO; 13 | using System.Text.RegularExpressions; 14 | 15 | namespace Client 16 | { 17 | public partial class MainForm : Form 18 | { 19 | private const string DirLabel = "<文件夹>"; 20 | private Credential cred; 21 | private string path = ""; 22 | public MainForm(Credential cred) 23 | { 24 | this.cred = cred; 25 | InitializeComponent(); 26 | } 27 | 28 | private void MainForm_Load(object sender, EventArgs e) 29 | { 30 | LoadFileList(); 31 | } 32 | private void LoadFileList() 33 | { 34 | listView1.Items.Clear(); 35 | listView1.Enabled = false; 36 | toolStripButton1.Enabled = false; 37 | toolStripLabel1.Text = path == "" ? "/" : path; 38 | Application.DoEvents(); 39 | var res = Operation.GetFileList("/" + path, cred); 40 | if (res.success == false || res.errno != 0) 41 | { 42 | MessageBox.Show("Error: " + res.exception); 43 | path = ""; 44 | } 45 | else 46 | { 47 | if (path != "") listView1.Items.Add(new ListViewItem(new[] { "", ".." })); 48 | foreach (var item in res.list) 49 | { 50 | listView1.Items.Add(new ListViewItem(new[] { "", item.server_filename, item.isdir == 0 ? BytesToString(item.size) : DirLabel })); 51 | } 52 | } 53 | listView1.Enabled = true; 54 | toolStripButton1.Enabled = true; 55 | } 56 | private static string BytesToString(long byteCount) 57 | { 58 | string[] suf = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; //Longs run out around EB 59 | if (byteCount == 0) 60 | return "0" + suf[0]; 61 | long bytes = Math.Abs(byteCount); 62 | int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024))); 63 | double num = Math.Round(bytes / Math.Pow(1024, place), 1); 64 | return (Math.Sign(byteCount) * num).ToString() + suf[place]; 65 | } 66 | 67 | private void toolStripButton1_Click(object sender, EventArgs e) 68 | { 69 | LoadFileList(); 70 | } 71 | 72 | private void listView1_DoubleClick(object sender, EventArgs e) 73 | { 74 | if (listView1.SelectedItems.Count > 0) 75 | { 76 | var line = listView1.SelectedItems[0]; 77 | if (line.SubItems.Count == 2 || line.SubItems[2].Text == DirLabel) 78 | { 79 | if (line.SubItems[1].Text == "..") 80 | path = path.Substring(0, path.LastIndexOf('/')); 81 | else 82 | path += "/" + line.SubItems[1].Text; 83 | LoadFileList(); 84 | } 85 | else 86 | { 87 | listView1.Enabled = false; 88 | toolStripButton1.Enabled = false; 89 | Application.DoEvents(); 90 | var pwd = GeneratePwd(); 91 | var sres = Operation.Share(new[] { path + "/" + line.SubItems[1].Text }, cred, pwd); 92 | try 93 | { 94 | if (sres.success == false || sres.errno != 0) throw sres.exception; 95 | using (var wc = new WebClient()) 96 | { 97 | var str = wc.DownloadString("http://stomakun.me:9999/" + Uri.EscapeDataString(sres.link) + "/" + pwd); 98 | if (str.Contains("Error:") || !str.Contains("http://")) throw new Exception(str); 99 | ShowLinks(str); 100 | } 101 | } 102 | catch (Exception ex) 103 | { 104 | MessageBox.Show(ex.Message); 105 | } 106 | listView1.Enabled = true; 107 | toolStripButton1.Enabled = true; 108 | } 109 | } 110 | } 111 | private void ShowLinks(string str) 112 | { 113 | using(var sw=new StreamWriter("link.html")) 114 | { 115 | var html = ""; 116 | var i = 1; 117 | var del = "\n"; 118 | if (str.Contains("\r\n")) del = "\r\n"; 119 | else if (str.Contains("\r")) del = "\r"; 120 | foreach (var item in str.Split(new[] { del }, StringSplitOptions.RemoveEmptyEntries)) 121 | { 122 | var match = Regex.Match(item, "https?:\\/\\/(.+?)\\/"); 123 | html += "

下载地址" + i + (match.Success ? " (" + match.Groups[1].Value + ")" : "") + "

"; 124 | i++; 125 | } 126 | sw.WriteLine(html); 127 | } 128 | System.Diagnostics.Process.Start("link.html"); 129 | } 130 | private void MainForm_FormClosing(object sender, FormClosingEventArgs e) 131 | { 132 | Application.Exit(); 133 | } 134 | private string GeneratePwd() 135 | { 136 | var sb = new StringBuilder(); 137 | var rand = new Random(); 138 | for(int i = 0; i < 4; i++) 139 | { 140 | var type = rand.Next(3); 141 | if (type == 0) sb.Append((char)('0' + rand.Next(10))); 142 | else if (type == 1) sb.Append((char)('a' + rand.Next(26))); 143 | else if (type == 2) sb.Append((char)('A' + rand.Next(26))); 144 | } 145 | return sb.ToString(); 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /BaiduOldDriver/Client/MainForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /BaiduOldDriver/Client/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace Client 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// 应用程序的主入口点。 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new LoginForm()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /BaiduOldDriver/Client/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("Client")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Client")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("19ac20f7-9932-42c5-aa0c-95b09572a55d")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /BaiduOldDriver/Client/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本: 4.0.30319.42000 5 | // 6 | // 对此文件的更改可能导致不正确的行为,如果 7 | // 重新生成代码,则所做更改将丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Client.Properties 12 | { 13 | 14 | 15 | /// 16 | /// 强类型资源类,用于查找本地化字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// 返回此类使用的缓存 ResourceManager 实例。 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Client.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// 覆盖当前线程的 CurrentUICulture 属性 56 | /// 使用此强类型的资源类的资源查找。 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /BaiduOldDriver/Client/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /BaiduOldDriver/Client/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Client.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /BaiduOldDriver/Client/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BaiduOldDriver/Connoisseur/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /BaiduOldDriver/Connoisseur/Connoisseur.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {830F3B0B-9F4F-4720-9F14-A25EAF37410C} 8 | Exe 9 | Properties 10 | Connoisseur 11 | Connoisseur 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | {74eca1bf-6508-417d-bc57-db00daeca618} 54 | NetDisk 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /BaiduOldDriver/Connoisseur/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using NetDisk; 7 | using System.IO; 8 | using System.Net; 9 | using System.Text.RegularExpressions; 10 | using System.Threading; 11 | 12 | namespace Connoisseur 13 | { 14 | class Program 15 | { 16 | class Link 17 | { 18 | public string hash; 19 | public string name; 20 | } 21 | static void CheckSuccess(Result result) 22 | { 23 | if (!result.success) 24 | { 25 | Console.WriteLine(result.exception); 26 | Console.ReadLine(); 27 | Environment.Exit(-1); 28 | } 29 | } 30 | static Credential Login() 31 | { 32 | Console.Write("Username: "); 33 | var username = Console.ReadLine(); 34 | Console.Write("Password: "); 35 | var password = Console.ReadLine(); 36 | var checkResult = Authentication.LoginCheck(username); 37 | CheckSuccess(checkResult); 38 | if (checkResult.needVCode) 39 | { 40 | File.WriteAllBytes("vcode.png", checkResult.image); 41 | Console.WriteLine("Verification code required. Input the text in vcode.png."); 42 | try 43 | { 44 | System.Diagnostics.Process.Start("vcode.png"); 45 | } 46 | catch (Exception) { } 47 | checkResult.verifyCode = Console.ReadLine(); 48 | } 49 | else Console.WriteLine("Verification code NOT required."); 50 | var loginResult = Authentication.Login(username, password, checkResult); 51 | CheckSuccess(loginResult); 52 | return loginResult.credential; 53 | } 54 | static string GetName(string str) 55 | { 56 | try 57 | { 58 | var match = Regex.Match(str, "decodeURIComponent\\((.*?)\\);<"); 59 | if (!match.Success) return null; 60 | var esc = string.Concat(match.Groups[1].Value.Split('+').Select(t => t.Replace("\"", ""))); 61 | return Uri.UnescapeDataString(esc).Replace("", "").Replace("", ""); 62 | } 63 | catch (Exception) 64 | { 65 | return null; 66 | } 67 | } 68 | static List Search(string keyword) 69 | { 70 | var ret = new List(); 71 | var wc = new WebClient(); 72 | Console.Write("Looking at search result page"); 73 | for (int i = 1; i <= 100; i++) 74 | { 75 | var url = "http://www.btmeet.org/search/" + Uri.EscapeDataString(keyword) + "/" + i + "-1.html"; 76 | Console.Write(" " + i); 77 | try 78 | { 79 | var str = wc.DownloadString(url); 80 | var matches = Regex.Matches(str, "a href=\"\\/wiki\\/([0-9a-f]+?).html(.*?)<\\/a>"); 81 | if (matches.Count == 0) break; 82 | foreach (Match match in matches) 83 | { 84 | var name = GetName(match.Groups[2].Value); 85 | ret.Add(new Link() { hash = match.Groups[1].Value, name = name == null ? match.Groups[1].Value : name }); 86 | } 87 | } 88 | catch (Exception ex) 89 | { 90 | Console.WriteLine("Error: " + ex.Message); 91 | } 92 | } 93 | wc.Dispose(); 94 | Console.WriteLine(); 95 | return ret; 96 | } 97 | static void Offline(List links, string path, Credential credential) 98 | { 99 | var count = 0; 100 | foreach (var link in links) 101 | { 102 | Console.Write("Adding " + link.name + " ... "); 103 | var list = Operation.QueryLinkFiles("magnet:?xt=urn:btih:" + link.hash, credential); 104 | if (!list.success) 105 | { 106 | Console.WriteLine("Query magnet link failed."); 107 | continue; 108 | } 109 | var res = Operation.AddOfflineTask("magnet:?xt=urn:btih:" + link.hash, path, credential, Enumerable.Range(1, list.files.Length).ToArray()); 110 | if (!res.success) Console.WriteLine("Add offline task failed."); 111 | else Console.WriteLine("Success with rapid = " + res.rapid_download); 112 | if (res.success && res.rapid_download == 0) 113 | { 114 | count++; 115 | if (count >= 5) 116 | { 117 | Console.Write("Too many concurrent tasks, wait 3 seconds ... "); 118 | Thread.Sleep(3000); 119 | var tasks = Operation.GetOfflineList(credential).tasks.Where(t => t.status != 0).ToArray(); 120 | if (tasks.Length > 0) 121 | { 122 | Console.Write("Abort incomplete tasks ... "); 123 | foreach (var task in tasks) 124 | { 125 | Operation.CancelOfflineTask(task.task_id, credential); 126 | } 127 | } 128 | count = 0; 129 | Console.WriteLine("Okay, move on."); 130 | } 131 | } 132 | } 133 | } 134 | static void CleanUp(Credential credential) 135 | { 136 | var tasks = Operation.GetOfflineList(credential); 137 | foreach (var task in tasks.tasks.Where(t => t.status != 0)) 138 | { 139 | Operation.CancelOfflineTask(task.task_id, credential); 140 | } 141 | Console.WriteLine(tasks.tasks.Count(t => t.status == 0) + " completed tasks."); 142 | Operation.ClearOfflineTask(credential); 143 | } 144 | static void Main(string[] args) 145 | { 146 | var credential = Login(); 147 | Console.WriteLine("Login OK, uid = " + credential.uid); 148 | Console.Write("Keyword: "); 149 | var keyword = Console.ReadLine(); 150 | Console.WriteLine("Searching magnet links ..."); 151 | var links = Search(keyword); 152 | Console.WriteLine("Search complete with " + links.Count + " results."); 153 | var folder = Operation.CreateFolder("/" + keyword, credential); 154 | CheckSuccess(folder); 155 | Console.WriteLine("Files will be saved to " + folder.path); 156 | Offline(links, folder.path, credential); 157 | Console.WriteLine("Cleaning up ..."); 158 | CleanUp(credential); 159 | Console.WriteLine("Done."); 160 | Console.ReadLine(); 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /BaiduOldDriver/Connoisseur/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("Connoisseur")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Connoisseur")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("830f3b0b-9f4f-4720-9f14-a25eaf37410c")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /BaiduOldDriver/Downloader/Adapter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Downloader 8 | { 9 | public abstract class Adapter 10 | { 11 | public abstract List GetURLList(); 12 | public abstract List GetBlockList(FileTask OfTask); 13 | public abstract long GetSize(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /BaiduOldDriver/Downloader/BaiduAdapter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using NetDisk; 7 | 8 | namespace Downloader 9 | { 10 | public class BaiduAdapter : Adapter 11 | { 12 | public Credential credential; 13 | public string path; 14 | public long size; 15 | public override List GetURLList() 16 | { 17 | return Operation.GetDownload(path, credential).urls.Select(e => e.url).Distinct().ToList(); 18 | } 19 | public override List GetBlockList(FileTask OfTask) 20 | { 21 | var ret = new List(); 22 | long pos = 0; 23 | while(pos < size) 24 | { 25 | var length = Math.Min(size - pos, 1024 * 1024); 26 | var block = new Block(); 27 | block.OfTask = OfTask; 28 | block.Start = pos; 29 | block.Length = length; 30 | ret.Add(block); 31 | pos += length; 32 | } 33 | return ret; 34 | } 35 | public override long GetSize() 36 | { 37 | return size; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /BaiduOldDriver/Downloader/Block.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Downloader 8 | { 9 | public class Block 10 | { 11 | public FileTask OfTask; 12 | public List WorkingSource = new List(); 13 | public long Start; 14 | public long Length; 15 | public bool Completed; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /BaiduOldDriver/Downloader/DownloadSource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace Downloader 10 | { 11 | public class DownloadSource 12 | { 13 | private FileTask OfTask; 14 | public string URL; 15 | public int FailCount; 16 | private long Downloaded; 17 | private WebDownload wc; 18 | private bool Closed; 19 | private Block CurrentBlock; 20 | public DownloadSource(FileTask OfTask, string URL) 21 | { 22 | this.OfTask = OfTask; 23 | this.URL = URL; 24 | wc = new WebDownload(); 25 | wc.DownloadProgressChanged += (s, e) => 26 | { 27 | lock (this) 28 | Downloaded = e.BytesReceived; 29 | }; 30 | wc.DownloadDataCompleted += Wc_DownloadDataCompleted; 31 | Wc_DownloadDataCompleted(null, null); 32 | } 33 | private void Wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e) 34 | { 35 | lock (this) 36 | { 37 | if (Closed) 38 | { 39 | wc.Dispose(); 40 | return; 41 | } 42 | if (e != null && !e.Cancelled) 43 | { 44 | if (e.Error == null) 45 | { 46 | Downloaded = 0; 47 | OfTask.ReportSuccess(CurrentBlock, this, e.Result); 48 | } 49 | else 50 | { 51 | OfTask.ReportFailure(CurrentBlock, this); 52 | FailCount++; 53 | if (FailCount >= 10) 54 | { 55 | Close(); 56 | return; 57 | } 58 | } 59 | } 60 | CurrentBlock = OfTask.GetBlock(this); 61 | if (CurrentBlock == null) 62 | { 63 | Abort(); 64 | return; 65 | } 66 | wc.from = CurrentBlock.Start; 67 | wc.to = CurrentBlock.Start + CurrentBlock.Length - 1; 68 | wc.DownloadDataAsync(new Uri(URL)); 69 | } 70 | } 71 | public void Abort() 72 | { 73 | try 74 | { 75 | wc.CancelAsync(); 76 | } 77 | catch (Exception) { } 78 | } 79 | public void Close() 80 | { 81 | lock (this) 82 | Closed = true; 83 | Abort(); 84 | } 85 | public bool IsClosed() 86 | { 87 | lock (this) 88 | return Closed; 89 | } 90 | public long GetDownloadedBytes() 91 | { 92 | lock (this) 93 | return Downloaded; 94 | } 95 | } 96 | public class WebDownload : WebClient 97 | { 98 | public long from, to; 99 | protected override WebRequest GetWebRequest(Uri address) 100 | { 101 | var request = (HttpWebRequest)WebRequest.Create(address); 102 | request.AddRange(from, to); 103 | return request; 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /BaiduOldDriver/Downloader/Downloader.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {799C6C77-79D2-48EA-A56D-912EEC46B138} 8 | Library 9 | Properties 10 | Downloader 11 | Downloader 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | {74eca1bf-6508-417d-bc57-db00daeca618} 54 | NetDisk 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /BaiduOldDriver/Downloader/FileTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace Downloader 10 | { 11 | public class FileTask 12 | { 13 | public string SavePath; 14 | private long Downloaded; 15 | public List DownloadSources = new List(); 16 | public List Blocks = new List(); 17 | public LinkedList PendingBlocks = new LinkedList(); 18 | public LinkedList WorkingBlocks = new LinkedList(); 19 | private FileStream LocalFile; 20 | private Adapter OfAdapter; 21 | private Thread RefreshThread; 22 | private int ReSourceCount; 23 | private int DownloadSourcesCountAll; 24 | public bool Failed; 25 | public FileTask(Adapter OfAdapter, string SavePath) 26 | { 27 | this.OfAdapter = OfAdapter; 28 | Blocks = OfAdapter.GetBlockList(this); 29 | Blocks.ForEach(b => PendingBlocks.AddLast(b)); 30 | LocalFile = File.Open(SavePath, FileMode.Create); 31 | LocalFile.SetLength(OfAdapter.GetSize()); 32 | RefreshThread = new Thread(new ThreadStart(Refresh)); 33 | RefreshThread.Start(); 34 | } 35 | public void Abort() 36 | { 37 | lock (this) 38 | { 39 | RefreshThread.Abort(); 40 | DownloadSources.ForEach(s => s.Close()); 41 | Failed = true; 42 | LocalFile.Dispose(); 43 | } 44 | } 45 | private void Refresh() 46 | { 47 | while (true) 48 | { 49 | if (IsCompleted()) 50 | { 51 | LocalFile.Close(); 52 | LocalFile = null; 53 | break; 54 | } 55 | DownloadSources.RemoveAll(s => s.IsClosed()); 56 | var needReSource = false; 57 | if (DownloadSources.Count * 2 <= DownloadSourcesCountAll) 58 | { 59 | ReSourceCount++; 60 | needReSource = true; 61 | } 62 | if (needReSource) 63 | { 64 | if (ReSourceCount > 100) 65 | { 66 | Failed = true; 67 | return; 68 | } 69 | DownloadSources = OfAdapter.GetURLList().Select(u => new DownloadSource(this, u)).ToList(); 70 | DownloadSourcesCountAll = DownloadSources.Count; 71 | } 72 | try 73 | { 74 | Thread.Sleep(1000); 75 | } 76 | catch (Exception) { } 77 | } 78 | } 79 | public bool IsCompleted() 80 | { 81 | lock(this) 82 | return PendingBlocks.Count == 0; 83 | } 84 | public Block GetBlock(DownloadSource Source) 85 | { 86 | Block ret = null; 87 | lock (this) 88 | { 89 | if (PendingBlocks.Count > 0) 90 | { 91 | ret = PendingBlocks.First.Value; 92 | PendingBlocks.RemoveFirst(); 93 | WorkingBlocks.AddLast(ret); 94 | } 95 | else if (WorkingBlocks.Count > 0) 96 | { 97 | ret = WorkingBlocks.FirstOrDefault(b => b.WorkingSource.Count < 3 && b.WorkingSource.All(o => o.URL != Source.URL)); 98 | } 99 | if (ret != null) 100 | { 101 | ret.WorkingSource.Add(Source); 102 | } 103 | } 104 | return ret; 105 | } 106 | public long GetDownloadedBytes() 107 | { 108 | lock(this) 109 | return Downloaded + WorkingBlocks.Select(b => b.WorkingSource.Max(s => s.GetDownloadedBytes())).Sum(); 110 | } 111 | public void ReportSuccess(Block OfBlock, DownloadSource Source, byte[] data) 112 | { 113 | if (OfBlock.Completed) return; 114 | OfBlock.Completed = true; 115 | if (OfBlock.WorkingSource.Count > 1) 116 | OfBlock.WorkingSource.ForEach(s => { if (s != Source) s.Abort(); }); 117 | lock (this) 118 | { 119 | WorkingBlocks.Remove(OfBlock); 120 | Downloaded += OfBlock.Length; 121 | if (LocalFile != null) 122 | { 123 | LocalFile.Seek(OfBlock.Start, SeekOrigin.Begin); 124 | LocalFile.Write(data, 0, data.Length); 125 | LocalFile.Flush(); 126 | } 127 | } 128 | } 129 | public void ReportFailure(Block OfBlock, DownloadSource Source) 130 | { 131 | lock (this) 132 | { 133 | OfBlock.WorkingSource.Remove(Source); 134 | if (OfBlock.WorkingSource.Count == 0) 135 | { 136 | WorkingBlocks.Remove(OfBlock); 137 | PendingBlocks.AddFirst(OfBlock); 138 | } 139 | } 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /BaiduOldDriver/Downloader/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("Downloader")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Downloader")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("799c6c77-79d2-48ea-a56d-912eec46b138")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /BaiduOldDriver/GoodSamaritan/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /BaiduOldDriver/GoodSamaritan/GoodSamaritan.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {58FA2E94-9F03-4B01-A9DE-CD585D1F1040} 8 | Exe 9 | Properties 10 | GoodSamaritan 11 | GoodSamaritan 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | {74eca1bf-6508-417d-bc57-db00daeca618} 56 | NetDisk 57 | 58 | 59 | 60 | 67 | -------------------------------------------------------------------------------- /BaiduOldDriver/GoodSamaritan/MyHttpServer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using NetDisk; 8 | using System.Threading; 9 | 10 | namespace GoodSamaritan 11 | { 12 | class MyHttpServer : HttpServer 13 | { 14 | private Credential cred; 15 | private Dictionary lasttime = new Dictionary(); 16 | public MyHttpServer(int port, Credential cred) 17 | : base(port) 18 | { 19 | this.cred = cred; 20 | new Thread(new ThreadStart(GC)).Start(); 21 | } 22 | public override void handleGETRequest(HttpProcessor p) 23 | { 24 | var ip = p.socket.Client.RemoteEndPoint.ToString().Split(':')[0]; 25 | lock (this) 26 | { 27 | if (lasttime.ContainsKey(ip) && (DateTime.Now - lasttime[ip]).TotalSeconds < 60.0) 28 | { 29 | try 30 | { 31 | p.writeSuccess(); 32 | p.outputStream.WriteLine("Error: Wait 60 seconds before next request"); 33 | } 34 | catch (Exception) { } 35 | return; 36 | } 37 | lasttime[ip] = DateTime.Now; 38 | } 39 | try 40 | { 41 | var args = p.http_url.Split('/'); 42 | var tres = Operation.Transfer(Uri.UnescapeDataString(args[1]), "/shared", cred, args[2]); 43 | if (tres.success == false || tres.errno != 0) throw tres.exception; 44 | var dres = Operation.GetDownload(tres.extra.list[0].to, cred); 45 | p.writeSuccess(); 46 | dres.urls.ToList().ForEach(u => p.outputStream.WriteLine(u.url)); 47 | } 48 | catch (Exception ex) 49 | { 50 | p.writeFailure(); p.outputStream.WriteLine(ex); 51 | } 52 | } 53 | public override void handlePOSTRequest(HttpProcessor p, StreamReader inputData) 54 | { 55 | p.writeFailure(); 56 | p.outputStream.WriteLine("Use GET"); 57 | } 58 | private void GC() 59 | { 60 | while (true) 61 | { 62 | lock (this) 63 | lasttime.Clear(); 64 | Thread.Sleep(600 * 1000); 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /BaiduOldDriver/GoodSamaritan/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NetDisk; 3 | using System.IO; 4 | using System.Threading; 5 | 6 | namespace GoodSamaritan 7 | { 8 | class Program 9 | { 10 | static void CheckSuccess(Result result) 11 | { 12 | if (!result.success) 13 | { 14 | Console.WriteLine(result.exception); 15 | Console.ReadLine(); 16 | Environment.Exit(-1); 17 | } 18 | } 19 | static Credential Login(string username, string password) 20 | { 21 | var checkResult = Authentication.LoginCheck(username); 22 | CheckSuccess(checkResult); 23 | if (checkResult.needVCode) 24 | { 25 | File.WriteAllBytes("vcode.png", checkResult.image); 26 | Console.WriteLine("Verification code required. Input the text in vcode.png."); 27 | checkResult.verifyCode = Console.ReadLine(); 28 | } 29 | else Console.WriteLine("Verification code NOT required."); 30 | var loginResult = Authentication.Login(username, password, checkResult); 31 | CheckSuccess(loginResult); 32 | Console.WriteLine(loginResult.credential); 33 | Console.WriteLine("uid: " + loginResult.credential.uid); 34 | return loginResult.credential; 35 | } 36 | static void Main(string[] args) 37 | { 38 | int port; 39 | if (args.Length!=3||!int.TryParse(args[0], out port)) 40 | { 41 | Console.WriteLine("Parameters: "); 42 | return; 43 | } 44 | var cred = Login(args[1], args[2]); 45 | HttpServer httpServer = new MyHttpServer(port, cred); 46 | var thread = new Thread(new ThreadStart(httpServer.listen)); 47 | thread.Start(); 48 | Console.WriteLine("Listening on port " + port); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /BaiduOldDriver/GoodSamaritan/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("GoodSamaritan")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("GoodSamaritan")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("58fa2e94-9f03-4b01-a9de-cd585d1f1040")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /BaiduOldDriver/GoodSamaritan/SimpleHttpServer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.IO; 4 | using System.Net; 5 | using System.Net.Sockets; 6 | using System.Text; 7 | using System.Threading; 8 | 9 | // offered to the public domain for any use with no restriction 10 | // and also with no warranty of any kind, please enjoy. - David Jeske. 11 | 12 | // simple HTTP explanation 13 | // http://www.jmarshall.com/easy/http/ 14 | 15 | namespace GoodSamaritan 16 | { 17 | 18 | public class HttpProcessor 19 | { 20 | public TcpClient socket; 21 | public HttpServer srv; 22 | 23 | private Stream inputStream; 24 | public StreamWriter outputStream; 25 | 26 | public String http_method; 27 | public String http_url; 28 | public String http_protocol_versionstring; 29 | public Hashtable httpHeaders = new Hashtable(); 30 | 31 | 32 | private static int MAX_POST_SIZE = 10 * 1024; // 10KB 33 | 34 | public HttpProcessor(TcpClient s, HttpServer srv) 35 | { 36 | this.socket = s; 37 | this.srv = srv; 38 | } 39 | 40 | 41 | private string streamReadLine(Stream inputStream) 42 | { 43 | int next_char; 44 | StringBuilder data = new StringBuilder(); 45 | while (true) 46 | { 47 | next_char = inputStream.ReadByte(); 48 | if (next_char == '\n') { break; } 49 | if (next_char == '\r') { continue; } 50 | if (next_char == -1) { Thread.Sleep(1); continue; }; 51 | data.Append(Convert.ToChar(next_char)); 52 | } 53 | return data.ToString(); 54 | } 55 | public void process() 56 | { 57 | // we can't use a StreamReader for input, because it buffers up extra data on us inside it's 58 | // "processed" view of the world, and we want the data raw after the headers 59 | inputStream = new BufferedStream(socket.GetStream()); 60 | 61 | // we probably shouldn't be using a streamwriter for all output from handlers either 62 | outputStream = new StreamWriter(new BufferedStream(socket.GetStream())); 63 | try 64 | { 65 | parseRequest(); 66 | readHeaders(); 67 | if (http_method.Equals("GET")) 68 | { 69 | handleGETRequest(); 70 | } 71 | else if (http_method.Equals("POST")) 72 | { 73 | handlePOSTRequest(); 74 | } 75 | } 76 | catch (Exception e) 77 | { 78 | //Console.WriteLine("Exception: " + e.ToString()); 79 | writeFailure(); 80 | } 81 | outputStream.Flush(); 82 | // bs.Flush(); // flush any remaining output 83 | inputStream = null; outputStream = null; // bs = null; 84 | socket.Close(); 85 | } 86 | 87 | public void parseRequest() 88 | { 89 | String request = streamReadLine(inputStream); 90 | string[] tokens = request.Split(' '); 91 | if (tokens.Length != 3) 92 | { 93 | throw new Exception("invalid http request line"); 94 | } 95 | http_method = tokens[0].ToUpper(); 96 | http_url = tokens[1]; 97 | http_protocol_versionstring = tokens[2]; 98 | 99 | //Console.WriteLine("starting: " + request); 100 | } 101 | 102 | public void readHeaders() 103 | { 104 | //Console.WriteLine("readHeaders()"); 105 | String line; 106 | while ((line = streamReadLine(inputStream)) != null) 107 | { 108 | if (line.Equals("")) 109 | { 110 | //Console.WriteLine("got headers"); 111 | return; 112 | } 113 | 114 | int separator = line.IndexOf(':'); 115 | if (separator == -1) 116 | { 117 | throw new Exception("invalid http header line: " + line); 118 | } 119 | String name = line.Substring(0, separator); 120 | int pos = separator + 1; 121 | while ((pos < line.Length) && (line[pos] == ' ')) 122 | { 123 | pos++; // strip any spaces 124 | } 125 | 126 | string value = line.Substring(pos, line.Length - pos); 127 | //Console.WriteLine("header: {0}:{1}", name, value); 128 | httpHeaders[name] = value; 129 | } 130 | } 131 | 132 | public void handleGETRequest() 133 | { 134 | srv.handleGETRequest(this); 135 | } 136 | 137 | private const int BUF_SIZE = 4096; 138 | public void handlePOSTRequest() 139 | { 140 | // this post data processing just reads everything into a memory stream. 141 | // this is fine for smallish things, but for large stuff we should really 142 | // hand an input stream to the request processor. However, the input stream 143 | // we hand him needs to let him see the "end of the stream" at this content 144 | // length, because otherwise he won't know when he's seen it all! 145 | 146 | //Console.WriteLine("get post data start"); 147 | int content_len = 0; 148 | MemoryStream ms = new MemoryStream(); 149 | if (this.httpHeaders.ContainsKey("Content-Length")) 150 | { 151 | content_len = Convert.ToInt32(this.httpHeaders["Content-Length"]); 152 | if (content_len > MAX_POST_SIZE) 153 | { 154 | throw new Exception( 155 | String.Format("POST Content-Length({0}) too big for this simple server", 156 | content_len)); 157 | } 158 | byte[] buf = new byte[BUF_SIZE]; 159 | int to_read = content_len; 160 | while (to_read > 0) 161 | { 162 | //Console.WriteLine("starting Read, to_read={0}", to_read); 163 | 164 | int numread = this.inputStream.Read(buf, 0, Math.Min(BUF_SIZE, to_read)); 165 | //Console.WriteLine("read finished, numread={0}", numread); 166 | if (numread == 0) 167 | { 168 | if (to_read == 0) 169 | { 170 | break; 171 | } 172 | else 173 | { 174 | throw new Exception("client disconnected during post"); 175 | } 176 | } 177 | to_read -= numread; 178 | ms.Write(buf, 0, numread); 179 | } 180 | ms.Seek(0, SeekOrigin.Begin); 181 | } 182 | //Console.WriteLine("get post data end"); 183 | srv.handlePOSTRequest(this, new StreamReader(ms)); 184 | 185 | } 186 | 187 | public void writeSuccess(string content_type = "text/html") 188 | { 189 | outputStream.WriteLine("HTTP/1.0 200 OK"); 190 | outputStream.WriteLine("Content-Type: " + content_type); 191 | outputStream.WriteLine("Connection: close"); 192 | outputStream.WriteLine(""); 193 | } 194 | 195 | public void writeFailure() 196 | { 197 | outputStream.WriteLine("HTTP/1.0 400 Bad request"); 198 | outputStream.WriteLine("Connection: close"); 199 | outputStream.WriteLine(""); 200 | } 201 | } 202 | 203 | public abstract class HttpServer 204 | { 205 | 206 | protected int port; 207 | TcpListener listener; 208 | bool is_active = true; 209 | 210 | public HttpServer(int port) 211 | { 212 | this.port = port; 213 | } 214 | 215 | public void listen() 216 | { 217 | listener = new TcpListener(IPAddress.Any, port); 218 | listener.Start(); 219 | while (is_active) 220 | { 221 | try 222 | { 223 | TcpClient s = listener.AcceptTcpClient(); 224 | HttpProcessor processor = new HttpProcessor(s, this); 225 | Thread thread = new Thread(new ThreadStart(processor.process)); 226 | thread.Start(); 227 | Thread.Sleep(1); 228 | } 229 | catch (Exception) { } 230 | } 231 | } 232 | 233 | public abstract void handleGETRequest(HttpProcessor p); 234 | public abstract void handlePOSTRequest(HttpProcessor p, StreamReader inputData); 235 | } 236 | } 237 | 238 | 239 | 240 | -------------------------------------------------------------------------------- /BaiduOldDriver/NetDisk/Authentication.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Text; 4 | using System.Text.RegularExpressions; 5 | 6 | namespace NetDisk 7 | { 8 | public static class Authentication 9 | { 10 | public static bool IsLoggedIn(Credential credential) 11 | { 12 | var res = Operation.GetQuota(credential); 13 | if (res == null || res.errno != 0) return false; 14 | else return true; 15 | } 16 | public static LoginResult Login(string username, string password, LoginCheckResult checkResult) 17 | { 18 | var result = new LoginResult(); 19 | try 20 | { 21 | using (var wc = new CookieAwareWebClient()) 22 | { 23 | wc.Cookies.Add(checkResult.baiduid); 24 | var ltoken = checkResult.ltoken; 25 | var lstr = "loginmerge=true&token=" + ltoken + "&tpl=netdisk&username=" + Uri.EscapeDataString(username) + "&password=" + Uri.EscapeDataString(password); 26 | if (checkResult.needVCode) lstr += "&codestring=" + checkResult.codeString + "&verifycode=" + Uri.EscapeDataString(checkResult.verifyCode); 27 | wc.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded"); 28 | var str = Encoding.UTF8.GetString(wc.UploadData("https://passport.baidu.com/v2/api/?login", Encoding.UTF8.GetBytes(lstr))); 29 | var match = Regex.Match(str, "error=(\\d+)"); 30 | var errno = match.Success ? int.Parse(match.Groups[1].Value) : 0; 31 | if (errno != 0) 32 | { 33 | result.exception = new Exception("Login returned error = " + errno); 34 | result.errno = errno; 35 | } 36 | else 37 | { 38 | str = wc.DownloadString("https://passport.baidu.com/v3/login/api/auth/?return_type=3&tpl=netdisk&u=http%3A%2F%2Fpan.baidu.com%2Fdisk%2Fhome"); 39 | long uid = 0; 40 | match = Regex.Match(str, "\"uk\"\\s*:\\s*(\\d+)"); 41 | if (match.Success) long.TryParse(match.Groups[1].Value, out uid); 42 | string baiduid = null, bduss = null, stoken = null; 43 | foreach (Cookie cookie in wc.Cookies.GetAllCookies()) 44 | { 45 | if (cookie.Name.ToLower() == "baiduid") baiduid = cookie.Value; 46 | else if (cookie.Name.ToLower() == "bduss") bduss = cookie.Value; 47 | else if (cookie.Name.ToLower() == "stoken" && cookie.Domain.ToLower().Contains("pan.")) stoken = cookie.Value; 48 | } 49 | if (baiduid != null && bduss != null && stoken != null) 50 | { 51 | result.credential = new Credential(baiduid, bduss, stoken, uid); 52 | result.success = true; 53 | } 54 | else result.exception = new Exception("Cannot find required cookies."); 55 | } 56 | } 57 | } 58 | catch (Exception ex) 59 | { 60 | result.exception = ex; 61 | } 62 | return result; 63 | } 64 | public static LoginCheckResult LoginCheck(string username) 65 | { 66 | var result = new LoginCheckResult(); 67 | try 68 | { 69 | using (var wc = new CookieAwareWebClient()) 70 | { 71 | wc.DownloadData("http://pan.baidu.com/"); 72 | Cookie baiduid = null; 73 | foreach (Cookie cookie in wc.Cookies.GetAllCookies()) 74 | { 75 | if (cookie.Name.ToLower() == "baiduid") baiduid = cookie; 76 | } 77 | if (baiduid == null) throw new Exception("Cannot obtain BAIDUID."); 78 | result.baiduid = baiduid; 79 | var str = wc.DownloadString("https://passport.baidu.com/v2/api/?getapi&tpl=netdisk&subpro=netdisk_web&apiver=v3"); 80 | var ltoken = Regex.Match(str, "\"token\"\\s*:\\s*\"(.+?)\"").Groups[1].Value; 81 | result.ltoken = ltoken; 82 | str = wc.DownloadString("https://passport.baidu.com/v2/api/?logincheck&token=" + ltoken + "&tpl=netdisk&subpro=netdisk_web&apiver=v3&username=" + Uri.EscapeDataString(username)); 83 | var codeString = Regex.Match(str, "\"codeString\"\\s*:\\s*\"(.*?)\"").Groups[1].Value; 84 | if (codeString == "") 85 | { 86 | result.success = true; 87 | } 88 | else 89 | { 90 | result.image = wc.DownloadData("https://passport.baidu.com/cgi-bin/genimage?" + codeString); 91 | result.success = true; 92 | result.needVCode = true; 93 | result.codeString = codeString; 94 | } 95 | } 96 | } 97 | catch (Exception ex) 98 | { 99 | result.exception = ex; 100 | } 101 | return result; 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /BaiduOldDriver/NetDisk/CRC32.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Damien Guard. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 4 | // Originally published at http://damieng.com/blog/2006/08/08/calculating_crc32_in_c_and_net 5 | 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Security.Cryptography; 9 | 10 | namespace DamienG.Security.Cryptography 11 | { 12 | /// 13 | /// Implements a 32-bit CRC hash algorithm compatible with Zip etc. 14 | /// 15 | /// 16 | /// Crc32 should only be used for backward compatibility with older file formats 17 | /// and algorithms. It is not secure enough for new applications. 18 | /// If you need to call multiple times for the same data either use the HashAlgorithm 19 | /// interface or remember that the result of one Compute call needs to be ~ (XOR) before 20 | /// being passed in as the seed for the next Compute call. 21 | /// 22 | public sealed class Crc32 : HashAlgorithm 23 | { 24 | public const UInt32 DefaultPolynomial = 0xedb88320u; 25 | public const UInt32 DefaultSeed = 0xffffffffu; 26 | 27 | static UInt32[] defaultTable; 28 | 29 | readonly UInt32 seed; 30 | readonly UInt32[] table; 31 | UInt32 hash; 32 | 33 | public Crc32() 34 | : this(DefaultPolynomial, DefaultSeed) 35 | { 36 | } 37 | 38 | public Crc32(UInt32 polynomial, UInt32 seed) 39 | { 40 | table = InitializeTable(polynomial); 41 | this.seed = hash = seed; 42 | } 43 | 44 | public override void Initialize() 45 | { 46 | hash = seed; 47 | } 48 | 49 | protected override void HashCore(byte[] array, int ibStart, int cbSize) 50 | { 51 | hash = CalculateHash(table, hash, array, ibStart, cbSize); 52 | } 53 | 54 | protected override byte[] HashFinal() 55 | { 56 | var hashBuffer = UInt32ToBigEndianBytes(~hash); 57 | HashValue = hashBuffer; 58 | return hashBuffer; 59 | } 60 | 61 | public override int HashSize { get { return 32; } } 62 | 63 | public static UInt32 Compute(byte[] buffer) 64 | { 65 | return Compute(DefaultSeed, buffer); 66 | } 67 | 68 | public static UInt32 Compute(UInt32 seed, byte[] buffer) 69 | { 70 | return Compute(DefaultPolynomial, seed, buffer); 71 | } 72 | 73 | public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer) 74 | { 75 | return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length); 76 | } 77 | 78 | static UInt32[] InitializeTable(UInt32 polynomial) 79 | { 80 | if (polynomial == DefaultPolynomial && defaultTable != null) 81 | return defaultTable; 82 | 83 | var createTable = new UInt32[256]; 84 | for (var i = 0; i < 256; i++) 85 | { 86 | var entry = (UInt32)i; 87 | for (var j = 0; j < 8; j++) 88 | if ((entry & 1) == 1) 89 | entry = (entry >> 1) ^ polynomial; 90 | else 91 | entry = entry >> 1; 92 | createTable[i] = entry; 93 | } 94 | 95 | if (polynomial == DefaultPolynomial) 96 | defaultTable = createTable; 97 | 98 | return createTable; 99 | } 100 | 101 | static UInt32 CalculateHash(UInt32[] table, UInt32 seed, IList buffer, int start, int size) 102 | { 103 | var hash = seed; 104 | for (var i = start; i < start + size; i++) 105 | hash = (hash >> 8) ^ table[buffer[i] ^ hash & 0xff]; 106 | return hash; 107 | } 108 | 109 | static byte[] UInt32ToBigEndianBytes(UInt32 uint32) 110 | { 111 | var result = BitConverter.GetBytes(uint32); 112 | 113 | if (BitConverter.IsLittleEndian) 114 | Array.Reverse(result); 115 | 116 | return result; 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /BaiduOldDriver/NetDisk/CookieAwareWebClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace NetDisk 5 | { 6 | public class CookieAwareWebClient : WebClient 7 | { 8 | public CookieContainer Cookies { get; set; } 9 | public Uri Uri { get; set; } 10 | Uri _responseUri; 11 | public Uri ResponseUri 12 | { 13 | get { return _responseUri; } 14 | } 15 | public CookieAwareWebClient() 16 | : this(new CookieContainer()) 17 | { 18 | } 19 | 20 | public CookieAwareWebClient(CookieContainer cookies) 21 | { 22 | this.Cookies = cookies; 23 | } 24 | 25 | protected override WebRequest GetWebRequest(Uri address) 26 | { 27 | WebRequest request = base.GetWebRequest(address); 28 | if (request is HttpWebRequest) 29 | { 30 | ClearCookiesVersion(); 31 | (request as HttpWebRequest).CookieContainer = this.Cookies; 32 | } 33 | HttpWebRequest httpRequest = (HttpWebRequest)request; 34 | httpRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; 35 | return httpRequest; 36 | } 37 | protected override WebResponse GetWebResponse(WebRequest request) 38 | { 39 | WebResponse response = base.GetWebResponse(request); 40 | _responseUri = response.ResponseUri; 41 | return response; 42 | } 43 | private void ClearCookiesVersion() 44 | { 45 | var cc = new CookieContainer(); 46 | foreach (Cookie cookie in Cookies.GetAllCookies()) 47 | { 48 | cookie.Version = 0; 49 | cc.Add(cookie); 50 | } 51 | Cookies = cc; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /BaiduOldDriver/NetDisk/Credential.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | 3 | namespace NetDisk 4 | { 5 | public class Credential 6 | { 7 | public string baiduid { get; } 8 | public string bduss { get; } 9 | public string stoken { get; } 10 | public long uid { get; } 11 | private string cookieString; 12 | public Credential(string baiduid, string bduss, string stoken, long uid) 13 | { 14 | this.baiduid = baiduid; 15 | this.bduss = bduss; 16 | this.stoken = stoken; 17 | this.uid = uid; 18 | cookieString = "BAIDUID=" + baiduid + "; BDUSS=" + bduss + "; STOKEN=" + stoken; 19 | } 20 | public static implicit operator string(Credential credential) 21 | { 22 | return credential.cookieString; 23 | } 24 | public static implicit operator CookieCollection(Credential credential) 25 | { 26 | var c = new CookieCollection(); 27 | c.Add(new Cookie("BAIDUID", credential.baiduid, "/", ".baidu.com")); 28 | c.Add(new Cookie("BDUSS", credential.bduss, "/", ".baidu.com")); 29 | c.Add(new Cookie("STOKEN", credential.stoken, "/", ".pan.baidu.com")); 30 | return c; 31 | } 32 | public string Serialize() 33 | { 34 | return baiduid + "$" + bduss + "$" + stoken + "$" + uid; 35 | } 36 | public static Credential Deserialize(string str) 37 | { 38 | var tokens = str.Split('$'); 39 | return new Credential(tokens[0], tokens[1], tokens[2], long.Parse(tokens[3])); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /BaiduOldDriver/NetDisk/Extension.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Linq; 3 | using System.Net; 4 | using System.Reflection; 5 | 6 | namespace NetDisk 7 | { 8 | public static class Extension 9 | { 10 | public static CookieCollection GetAllCookies(this CookieContainer container) 11 | { 12 | var allCookies = new CookieCollection(); 13 | var domainTableField = container.GetType().GetRuntimeFields().FirstOrDefault(x => x.Name == "m_domainTable"); 14 | var domains = (IDictionary)domainTableField.GetValue(container); 15 | 16 | foreach (var val in domains.Values) 17 | { 18 | var type = val.GetType().GetRuntimeFields().First(x => x.Name == "m_list"); 19 | var values = (IDictionary)type.GetValue(val); 20 | foreach (CookieCollection cookies in values.Values) 21 | { 22 | allCookies.Add(cookies); 23 | } 24 | } 25 | return allCookies; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /BaiduOldDriver/NetDisk/NetDisk.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {74ECA1BF-6508-417D-BC57-DB00DAECA618} 8 | Library 9 | Properties 10 | NetDisk 11 | NetDisk 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | False 39 | ..\Newtonsoft.Json.dll 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | Component 55 | 56 | 57 | 58 | 59 | 60 | 61 | Component 62 | 63 | 64 | 65 | 66 | 67 | 68 | 75 | -------------------------------------------------------------------------------- /BaiduOldDriver/NetDisk/Operation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Runtime.Serialization; 6 | using System.Text; 7 | using Newtonsoft.Json; 8 | using System.Text.RegularExpressions; 9 | using System.IO; 10 | 11 | namespace NetDisk 12 | { 13 | public static class Operation 14 | { 15 | public static QuotaResult GetQuota(Credential credential) 16 | { 17 | try 18 | { 19 | using (var wc = new WebClient()) 20 | { 21 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 22 | var res = wc.DownloadString("http://pan.baidu.com/api/quota?checkexpire=1&checkfree=1"); 23 | var obj = JsonConvert.DeserializeObject(res); 24 | obj.success = true; 25 | return obj; 26 | } 27 | } 28 | catch (Exception ex) 29 | { 30 | return new QuotaResult() { exception = ex }; 31 | } 32 | } 33 | public static UserInfoResult GetUserInfo(Credential credential) 34 | { 35 | try 36 | { 37 | if (credential.uid <= 0) throw new Exception("Invalid uid."); 38 | using (var wc = new WebClient()) 39 | { 40 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 41 | var res = wc.DownloadString("http://pan.baidu.com/api/user/getinfo?user_list=[" + credential.uid + "]"); 42 | var obj = JsonConvert.DeserializeObject(res); 43 | obj.success = true; 44 | return obj; 45 | } 46 | } 47 | catch (Exception ex) 48 | { 49 | return new UserInfoResult() { exception = ex }; 50 | } 51 | } 52 | public static FileListResult GetFileList(string path, Credential credential) 53 | { 54 | try 55 | { 56 | using (var wc = new WebClient()) 57 | { 58 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 59 | var res = wc.DownloadString("http://pan.baidu.com/api/list?page=1&num=10000000&dir=" + Uri.EscapeDataString(path)); 60 | var obj = JsonConvert.DeserializeObject(res); 61 | obj.success = true; 62 | return obj; 63 | } 64 | } 65 | catch (Exception ex) 66 | { 67 | return new FileListResult() { exception = ex }; 68 | } 69 | } 70 | public static ThumbnailResult GetThumbnail(string path, Credential credential, int width = 125, int height = 90, int quality = 100) 71 | { 72 | try 73 | { 74 | using (var wc = new WebClient()) 75 | { 76 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 77 | var res = wc.DownloadData("http://pcsdata.baidu.com/rest/2.0/pcs/thumbnail?app_id=250528&method=generate&path=" + Uri.EscapeDataString(path) + "&quality=" + quality + "&height=" + height + "&width=" + width); 78 | return new ThumbnailResult() { success = true, image = res }; 79 | } 80 | } 81 | catch (Exception ex) 82 | { 83 | return new ThumbnailResult() { exception = ex }; 84 | } 85 | } 86 | public static GetDownloadResult GetDownload(string path, Credential credential) 87 | { 88 | try 89 | { 90 | using (var wc = new WebClient()) 91 | { 92 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 93 | wc.Headers.Add(HttpRequestHeader.UserAgent, "netdisk;5.4.5.4;PC;PC-Windows;10.0.14393;WindowsBaiduYunGuanJia"); 94 | var res = wc.DownloadString("http://d.pcs.baidu.com/rest/2.0/pcs/file?app_id=250528&method=locatedownload&ver=4.0&path=" + Uri.EscapeDataString(path)); 95 | var obj = JsonConvert.DeserializeObject(res); 96 | obj.success = true; 97 | return obj; 98 | } 99 | } 100 | catch (Exception ex) 101 | { 102 | return new GetDownloadResult() { exception = ex }; 103 | } 104 | } 105 | public static FileOperationResult CreateFolder(string path, Credential credential) 106 | { 107 | try 108 | { 109 | using (var wc = new WebClient()) 110 | { 111 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 112 | wc.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded"); 113 | var str = "isdir=1&path=" + Uri.EscapeDataString(path); 114 | var res = wc.UploadData("http://pan.baidu.com/api/create?a=commit", Encoding.UTF8.GetBytes(str)); 115 | var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(res)); 116 | obj.success = true; 117 | return obj; 118 | } 119 | } 120 | catch (Exception ex) 121 | { 122 | return new FileOperationResult() { exception = ex }; 123 | } 124 | } 125 | public static FileOperationResult Copy(string path, string dest, string newname, Credential credential) 126 | { 127 | var str = "filelist=[{\"path\":\"" + Uri.EscapeDataString(path) + "\",\"dest\":\"" + Uri.EscapeDataString(dest) + "\",\"newname\":\"" + Uri.EscapeDataString(newname) + "\"}]"; 128 | return FileOp("http://pan.baidu.com/api/filemanager?opera=copy&clienttype=8", str, credential); 129 | } 130 | public static FileOperationResult Delete(string path, Credential credential) 131 | { 132 | var str = "filelist=[\"" + Uri.EscapeDataString(path) + "\"]"; 133 | return FileOp("http://pan.baidu.com/api/filemanager?opera=delete&clienttype=8", str, credential); 134 | } 135 | public static FileOperationResult Move(string path, string dest, string newname, Credential credential) 136 | { 137 | var str = "filelist=[{\"path\":\"" + Uri.EscapeDataString(path) + "\",\"dest\":\"" + Uri.EscapeDataString(dest) + "\",\"newname\":\"" + Uri.EscapeDataString(newname) + "\"}]"; 138 | return FileOp("http://pan.baidu.com/api/filemanager?opera=move&clienttype=8", str, credential); 139 | } 140 | public static FileOperationResult Rename(string path, string newname, Credential credential) 141 | { 142 | var str = "filelist=[{\"path\":\"" + Uri.EscapeDataString(path) + "\",\"newname\":\"" + Uri.EscapeDataString(newname) + "\"}]"; 143 | return FileOp("http://pan.baidu.com/api/filemanager?opera=rename&clienttype=8", str, credential); 144 | } 145 | private static FileOperationResult FileOp(string url, string str, Credential credential) 146 | { 147 | try 148 | { 149 | using (var wc = new WebClient()) 150 | { 151 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 152 | wc.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded"); 153 | var res = wc.UploadData(url, Encoding.UTF8.GetBytes(str)); 154 | var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(res)); 155 | if (obj.info.Length == 0 && obj.errno != 0) 156 | return new FileOperationResult() { success = true, errno = obj.errno }; 157 | else if (obj.info.Length == 0 || obj.errno != 0 && obj.info[0].errno == 0) 158 | throw new Exception("Response data malformat."); 159 | else 160 | return new FileOperationResult() { success = true, errno = obj.info[0].errno, path = obj.info[0].path }; 161 | } 162 | } 163 | catch (Exception ex) 164 | { 165 | return new FileOperationResult() { exception = ex }; 166 | } 167 | } 168 | public static OfflineListResult GetOfflineList(Credential credential) 169 | { 170 | try 171 | { 172 | using (var wc = new WebClient()) 173 | { 174 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 175 | var res1 = wc.DownloadString("http://pan.baidu.com/rest/2.0/services/cloud_dl?app_id=250528&method=list_task&need_task_info=1&status=255"); 176 | var ltr = JsonConvert.DeserializeObject(res1); 177 | if (ltr.task_info.Length == 0) return new OfflineListResult() { success = true, tasks = new OfflineListResult.Entry[0] }; 178 | var str = "method=query_task&op_type=1&task_ids=" + Uri.EscapeDataString(string.Join(",", ltr.task_info.Select(e => e.task_id.ToString()))); 179 | wc.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded"); 180 | var res2 = wc.UploadData("http://pan.baidu.com/rest/2.0/services/cloud_dl?app_id=250528", Encoding.UTF8.GetBytes(str)); 181 | var qtr = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(res2)); 182 | return new OfflineListResult() 183 | { 184 | tasks = ltr.task_info.Select(e => 185 | { 186 | var ai = qtr.task_info[e.task_id.ToString()]; 187 | return new OfflineListResult.Entry() 188 | { 189 | create_time = e.create_time, 190 | od_type = e.od_type, 191 | save_path = e.save_path, 192 | source_url = e.source_url, 193 | task_id = e.task_id, 194 | task_name = e.task_name, 195 | file_size = ai.file_size, 196 | finished_size = ai.finished_size, 197 | status = ai.status 198 | }; 199 | }).ToArray(), 200 | success = true 201 | }; 202 | } 203 | } 204 | catch (Exception ex) 205 | { 206 | return new OfflineListResult() { exception = ex }; 207 | } 208 | } 209 | public static Result CancelOfflineTask(long taskid, Credential credential) 210 | { 211 | return OfflineTaskOp(taskid, "cancel_task", credential); 212 | } 213 | public static Result DeleteOfflineTask(long taskid, Credential credential) 214 | { 215 | return OfflineTaskOp(taskid, "delete_task", credential); 216 | } 217 | public static Result ClearOfflineTask(Credential credential) 218 | { 219 | return OfflineTaskOp(0, "clear_task", credential); 220 | } 221 | private static Result OfflineTaskOp(long taskid, string oper, Credential credential) 222 | { 223 | try 224 | { 225 | using (var wc = new WebClient()) 226 | { 227 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 228 | wc.DownloadData("http://pan.baidu.com/rest/2.0/services/cloud_dl?app_id=250528&method=" + oper + "&task_id=" + taskid); 229 | return new Result() { success = true }; 230 | } 231 | } 232 | catch (Exception ex) 233 | { 234 | return new Result() { exception = ex }; 235 | } 236 | } 237 | public static QueryLinkResult QueryLinkFiles(string link, Credential credential) 238 | { 239 | try 240 | { 241 | using (var wc = new WebClient()) 242 | { 243 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 244 | wc.Headers.Add(HttpRequestHeader.UserAgent, "netdisk;5.4.5.4;PC;PC-Windows;10.0.14393;WindowsBaiduYunGuanJia"); 245 | if (link.StartsWith("magnet:", StringComparison.OrdinalIgnoreCase)) 246 | { 247 | var res = wc.DownloadString("http://pan.baidu.com/rest/2.0/services/cloud_dl?app_id=250528&clienttype=8&method=query_magnetinfo&source_url=" + Uri.EscapeDataString(link)); 248 | var obj = JsonConvert.DeserializeObject(res); 249 | return new QueryLinkResult() { success = true, files = obj.magnet_info }; 250 | } 251 | else if (link.EndsWith(".torrent", StringComparison.OrdinalIgnoreCase)) 252 | { 253 | var res = wc.DownloadString("http://pan.baidu.com/rest/2.0/services/cloud_dl?app_id=250528&clienttype=8&method=query_sinfo&type=2&source_path=" + Uri.EscapeDataString(link)); 254 | var obj = JsonConvert.DeserializeObject(res); 255 | return new QueryLinkResult() { success = true, files = obj.torrent_info.file_info }; 256 | } 257 | else throw new Exception("Not a magnet link or a torrent file."); 258 | } 259 | } 260 | catch (Exception ex) 261 | { 262 | return new QueryLinkResult() { exception = ex }; 263 | } 264 | } 265 | public static AddOfflineTaskResult AddOfflineTask(string link, string savepath, Credential credential, int[] selected = null, string sha1 = "") 266 | { 267 | try 268 | { 269 | var str = "method=add_task&save_path=" + Uri.EscapeDataString(savepath) + "&"; 270 | if (link.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || link.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) 271 | str += "type=0&source_url=" + Uri.EscapeDataString(link); 272 | else if (link.StartsWith("ed2k://", StringComparison.OrdinalIgnoreCase)) 273 | str += "type=3&source_url=" + Uri.EscapeDataString(link); 274 | else if (link.StartsWith("magnet:", StringComparison.OrdinalIgnoreCase)) 275 | str += "type=4&task_from=5&source_url=" + Uri.EscapeDataString(link) + "&selected_idx=" + string.Join(",", selected.Select(i => i.ToString())); 276 | else if (link.EndsWith(".torrent", StringComparison.OrdinalIgnoreCase)) 277 | str += "type=2&task_from=5&file_sha1=" + sha1 + "&source_path=" + Uri.EscapeDataString(link) + "&selected_idx=" + string.Join(",", selected.Select(i => i.ToString())); 278 | else throw new Exception("Link invalid."); 279 | using (var wc = new WebClient()) 280 | { 281 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 282 | wc.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded"); 283 | wc.Headers.Add(HttpRequestHeader.UserAgent, "netdisk;5.4.5.4;PC;PC-Windows;10.0.14393;WindowsBaiduYunGuanJia"); 284 | var res = wc.UploadData("http://pan.baidu.com/rest/2.0/services/cloud_dl?app_id=250528&clienttype=8", Encoding.UTF8.GetBytes(str)); 285 | var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(res)); 286 | obj.success = true; 287 | return obj; 288 | } 289 | } 290 | catch (Exception ex) 291 | { 292 | return new AddOfflineTaskResult() { exception = ex }; 293 | } 294 | } 295 | public static ShareResult Share(string[] pathlist, Credential credential, string pwd = null) 296 | { 297 | try 298 | { 299 | if (pwd != null && pwd.Length != 4) throw new Exception("Length of pwd must be 4."); 300 | var str = "path_list=[" + string.Join(",", pathlist.Select(p => '"' + Uri.EscapeDataString(p) + '"')) + "]&channel_list=[]&shorturl=1&"; 301 | if (pwd == null) str += "public=1&schannel=0"; 302 | else str += "public=0&schannel=4&pwd=" + pwd; 303 | var rand = new Random(); 304 | var logid = new string(Enumerable.Range(0, 100).Select(i => (char)('a' + rand.Next(26))).ToArray()); 305 | using (var wc = new WebClient()) 306 | { 307 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 308 | wc.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded"); 309 | var res = wc.UploadData("http://pan.baidu.com/share/pset?clienttype=8&channel=00000000000000000000000000000000&version=5.4.5.4&devuid=123456&logid=" + logid, Encoding.UTF8.GetBytes(str)); 310 | var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(res)); 311 | obj.success = true; 312 | return obj; 313 | } 314 | } 315 | catch (Exception ex) 316 | { 317 | return new ShareResult() { exception = ex }; 318 | } 319 | } 320 | public static TransferResult Transfer(string url, string path, Credential credential, string pwd = null) 321 | { 322 | try 323 | { 324 | using (var wc = new CookieAwareWebClient()) 325 | { 326 | wc.Cookies.Add(credential); 327 | var str = wc.DownloadString(url); 328 | var rurl = wc.ResponseUri.ToString(); 329 | string shareid = null, uk = null; 330 | if (rurl.Contains("/share/init")) 331 | { 332 | if (pwd == null) throw new Exception("Need password."); 333 | shareid = Regex.Match(rurl, "shareid=(\\d+)").Groups[1].Value; 334 | uk = Regex.Match(rurl, "uk=(\\d+)").Groups[1].Value; 335 | wc.Headers.Add(HttpRequestHeader.Referer, rurl); 336 | wc.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded"); 337 | var res = wc.UploadData("http://pan.baidu.com/share/verify?shareid=" + shareid + "&uk=" + uk, Encoding.UTF8.GetBytes("vcode=&vcode_str=&pwd=" + pwd)); 338 | var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(res)); 339 | if (obj.errno != 0) throw new Exception("Password verification returned errno = " + obj.errno); 340 | str = wc.DownloadString(url); 341 | } 342 | str = Regex.Match(str, "yunData.setData(.*)").Groups[1].Value.Trim(); 343 | str = str.Substring(1, str.Length - 3); 344 | var obj2 = JsonConvert.DeserializeObject(str); 345 | str = "path=" + Uri.EscapeDataString(path) + "&filelist=[" + string.Join(",", obj2.file_list.list.Select(e => "\"" + Uri.EscapeDataString(e.path) + "\"")) + "]"; 346 | wc.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded"); 347 | wc.Headers.Add(HttpRequestHeader.Referer, url); 348 | var rand = new Random(); 349 | var logid = new string(Enumerable.Range(0, 100).Select(i => (char)('a' + rand.Next(26))).ToArray()); 350 | var res2 = wc.UploadData("http://pan.baidu.com/share/transfer?channel=chunlei&clienttype=0&web=1&app_id=250528&ondup=newcopy&async=1&shareid=" + shareid + "&from=" + uk + "&logid=" + logid + "&bdstoken=" + obj2.bdstoken, Encoding.UTF8.GetBytes(str)); 351 | var obj3 = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(res2)); 352 | obj3.success = true; 353 | return obj3; 354 | } 355 | } 356 | catch (Exception ex) 357 | { 358 | return new TransferResult() { exception = ex }; 359 | } 360 | } 361 | public static CommitUploadResult SimpleUpload(string localpath, string remotepath, Credential credential, string host = "c.pcs.baidu.com") 362 | { 363 | try 364 | { 365 | var size = new FileInfo(localpath).Length; 366 | var mtime = (long)(new FileInfo(localpath).LastAccessTime.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; 367 | var md5 = UploadHelper.GetMD5HashFromFile(localpath); 368 | var str = "path=" + remotepath + "&size=" + size + "&isdir=0&block_list=[\"" + md5 + "\"]&autoinit=1&local_mtime=" + mtime + "&method=post"; 369 | using (var wc = new PatientWebClient()) 370 | { 371 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 372 | wc.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded"); 373 | var res = wc.UploadData("http://pan.baidu.com/api/precreate?clienttype=8", Encoding.UTF8.GetBytes(str)); 374 | var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(res)); 375 | if (obj.errno != 0) throw new Exception("precreate had errno = " + obj.errno); 376 | var boundary = GetBoundary(); 377 | wc.Headers.Add(HttpRequestHeader.ContentType, "multipart/form-data; boundary=" + boundary); 378 | str = "--" + boundary + "\r\nContent-Disposition: form-data; name=\"filename\"; filename=\"name\"\r\nContent-Type: application/octet-stream\r\n\r\n"; 379 | var str2 = "\r\n--" + boundary + "--\r\n"; 380 | var data = Encoding.UTF8.GetBytes(str).Concat(File.ReadAllBytes(localpath)).Concat(Encoding.UTF8.GetBytes(str2)).ToArray(); 381 | res = wc.UploadData("http://" + host + "/rest/2.0/pcs/superfile2?app_id=250528&method=upload&path=" + Uri.EscapeDataString(remotepath) + "&uploadid=" + Uri.EscapeDataString(obj.uploadid) + "&partseq=0&partoffset=0", data); 382 | str = "path=" + remotepath + "&size=" + size + "&isdir=0&uploadid=" + Uri.EscapeDataString(obj.uploadid) + "&block_list=[\"" + md5 + "\"]&method=post&rtype=2&sequence=1&mode=1&local_mtime=" + mtime; 383 | res = wc.UploadData("http://pan.baidu.com/api/create?a=commit&clienttype=8", Encoding.UTF8.GetBytes(str)); 384 | var obj2 = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(res)); 385 | obj2.success = true; 386 | return obj2; 387 | } 388 | } 389 | catch (Exception ex) 390 | { 391 | return new CommitUploadResult() { exception = ex }; 392 | } 393 | } 394 | public static RapidUploadResult RapidUpload(FileProperty prop, string path, Credential credential) 395 | { 396 | try 397 | { 398 | using (var wc = new WebClient()) 399 | { 400 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 401 | wc.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded"); 402 | var str = "path=" + Uri.EscapeDataString(path) + "&content-length=" + prop.size + "&content-md5=" + prop.md5 + "&slice-md5=" + prop.slice_md5 + "&content-crc32=" + prop.crc32 + "&local_mtime=" + prop.mtime + "&block_list=[" + string.Join(",", prop.blocks.Select(h => '"' + h + '"')) + "]&rtype=2"; 403 | var res = wc.UploadData("http://pan.baidu.com/api/rapidupload?clienttype=8", Encoding.UTF8.GetBytes(str)); 404 | var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(res)); 405 | obj.success = true; 406 | return obj; 407 | } 408 | } 409 | catch (Exception ex) 410 | { 411 | return new RapidUploadResult() { exception = ex }; 412 | } 413 | } 414 | public static InitUploadResult InitUpload(FileProperty prop, string path, Credential credential) 415 | { 416 | try 417 | { 418 | using (var wc = new WebClient()) 419 | { 420 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 421 | wc.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded"); 422 | var str = "path=" + Uri.EscapeDataString(path) + "&size=" + prop.size + "&isdir=0&local_mtime=" + prop.mtime + "&block_list=[" + string.Join(",", prop.blocks.Select(h => '"' + h + '"')) + "]&autoinit=1&method=post"; 423 | var res = wc.UploadData("http://pan.baidu.com/api/precreate?clienttype=8", Encoding.UTF8.GetBytes(str)); 424 | var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(res)); 425 | obj.success = true; 426 | return obj; 427 | } 428 | } 429 | catch (Exception ex) 430 | { 431 | return new InitUploadResult() { exception = ex }; 432 | } 433 | } 434 | public static Result UploadBlock(FileProperty prop, string path, InitUploadResult session, FileStream stream, int blockid, string host, Credential credential) 435 | { 436 | try 437 | { 438 | using (var wc = new PatientWebClient()) 439 | { 440 | var boundary = GetBoundary(); 441 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 442 | wc.Headers.Add(HttpRequestHeader.ContentType, "multipart/form-data; boundary=" + boundary); 443 | var str = "--" + boundary + "\r\nContent-Disposition: form-data; name=\"filename\"; filename=\"name\"\r\nContent-Type: application/octet-stream\r\n\r\n"; 444 | var str2 = "\r\n--" + boundary + "--\r\n"; 445 | stream.Seek((long)blockid * 4 * 1024 * 1024, SeekOrigin.Begin); 446 | var fdata = new byte[4 * 1024 * 1024]; 447 | var len = stream.Read(fdata, 0, fdata.Length); 448 | if (len < fdata.Length) 449 | { 450 | var arr = new byte[len]; 451 | Array.Copy(fdata, arr, len); 452 | fdata = arr; 453 | } 454 | var data = Encoding.UTF8.GetBytes(str).Concat(fdata).Concat(Encoding.UTF8.GetBytes(str2)).ToArray(); 455 | var res = wc.UploadData("http://" + host + "/rest/2.0/pcs/superfile2?app_id=250528&method=upload&path=" + Uri.EscapeDataString(path) + "&uploadid=" + Uri.EscapeDataString(session.uploadid) + "&partseq=" + blockid + "&partoffset=" + (long)blockid * 4 * 1024 * 1024, data); 456 | var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(res)); 457 | if (obj.md5 != prop.blocks[blockid]) throw new Exception("MD5 mismatch."); 458 | return new Result() { success = true }; 459 | } 460 | } 461 | catch (Exception ex) 462 | { 463 | return new Result() { exception = ex }; 464 | } 465 | } 466 | public static CommitUploadResult CommitUpload(FileProperty prop, string path, InitUploadResult session, Credential credential) 467 | { 468 | try 469 | { 470 | using (var wc = new WebClient()) 471 | { 472 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 473 | wc.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded"); 474 | var str = "path=" + path + "&size=" + prop.size + "&isdir=0&uploadid=" + Uri.EscapeDataString(session.uploadid) + "&block_list=[" + string.Join(",", prop.blocks.Select(h => '"' + h + '"')) + "]&method=post&rtype=2&sequence=1&mode=1&local_mtime=" + prop.mtime; 475 | var res = wc.UploadData("http://pan.baidu.com/api/create?a=commit&clienttype=8", Encoding.UTF8.GetBytes(str)); 476 | var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(res)); 477 | obj.success = true; 478 | return obj; 479 | } 480 | } 481 | catch (Exception ex) 482 | { 483 | return new CommitUploadResult() { exception = ex }; 484 | } 485 | } 486 | public static CommitUploadResult ChunkedUpload(string localpath, string remotepath, Credential credential) 487 | { 488 | try 489 | { 490 | var servers = GetUploadServers(credential); 491 | if (!servers.success) throw servers.exception; 492 | var prop = UploadHelper.GetFileProperty(localpath); 493 | var session = InitUpload(prop, remotepath, credential); 494 | if (!session.success) throw session.exception; 495 | if (session.errno != 0) throw new Exception("Init upload returned errno = " + session.errno); 496 | using (var fs = new FileStream(localpath, FileMode.Open)) 497 | { 498 | for(int i = 0; i < prop.blocks.Length; i++) 499 | { 500 | var res = UploadBlock(prop, remotepath, session, fs, i, servers.servers[0], credential); 501 | if (!res.success) throw res.exception; 502 | } 503 | } 504 | var comres = CommitUpload(prop, remotepath, session, credential); 505 | if (!comres.success) throw comres.exception; 506 | if (comres.errno != 0) throw new Exception("Commit upload returned errno = " + comres.errno); 507 | return comres; 508 | } 509 | catch (Exception ex) 510 | { 511 | return new CommitUploadResult() { exception = ex }; 512 | } 513 | } 514 | public static GetUploadServersResult GetUploadServers(Credential credential) 515 | { 516 | try 517 | { 518 | using (var wc = new WebClient()) 519 | { 520 | wc.Headers.Add(HttpRequestHeader.Cookie, credential); 521 | wc.Headers.Add(HttpRequestHeader.UserAgent, "netdisk;5.4.5.4;PC;PC-Windows;10.0.14393;WindowsBaiduYunGuanJia"); 522 | var res = wc.DownloadString("http://d.pcs.baidu.com/rest/2.0/pcs/file?app_id=250528&method=locateupload&esl=1&ehps=0&upload_version=2.0"); 523 | var obj = JsonConvert.DeserializeObject(res); 524 | return new GetUploadServersResult() { success = true, servers = obj.servers.Select(s => Regex.Match(s.server, ":\\/\\/(.+)$").Groups[1].Value).ToArray() }; 525 | } 526 | } 527 | catch (Exception ex) 528 | { 529 | return new GetUploadServersResult() { exception = ex }; 530 | } 531 | } 532 | private static string GetBoundary() 533 | { 534 | var rand = new Random(); 535 | var sb = new StringBuilder(); 536 | for (int i = 0; i < 28; i++) sb.Append('-'); 537 | for (int i = 0; i < 15; i++) sb.Append((char)(rand.Next(0, 26) + 'a')); 538 | var boundary = sb.ToString(); 539 | return boundary; 540 | } 541 | private class FileOpResult 542 | { 543 | public int errno; 544 | public Entry[] info; 545 | public class Entry 546 | { 547 | public int errno; 548 | public string path; 549 | } 550 | } 551 | private class ListTaskResult 552 | { 553 | public Entry[] task_info; 554 | public class Entry 555 | { 556 | public long create_time; 557 | public int od_type; 558 | public string save_path; 559 | public string source_url; 560 | public long task_id; 561 | public string task_name; 562 | } 563 | } 564 | private class QueryTaskResult 565 | { 566 | public Dictionary task_info; 567 | public class Entry 568 | { 569 | public long file_size; 570 | public long finished_size; 571 | public int status; 572 | } 573 | } 574 | private class QueryTorrentResult 575 | { 576 | public TorrentInfo torrent_info; 577 | public class TorrentInfo 578 | { 579 | public QueryLinkResult.Entry[] file_info; 580 | public string sha1; 581 | } 582 | } 583 | private class QueryMagnetResult 584 | { 585 | public QueryLinkResult.Entry[] magnet_info; 586 | } 587 | private class VerifyPwdResult 588 | { 589 | public int errno; 590 | } 591 | private class SharePageData 592 | { 593 | public string bdstoken; 594 | public FileList file_list; 595 | public class FileList 596 | { 597 | public Entry[] list; 598 | public class Entry 599 | { 600 | public string path; 601 | } 602 | } 603 | } 604 | private class SuperFileResponse 605 | { 606 | public string md5; 607 | } 608 | private class LocateUploadResponse 609 | { 610 | public Entry[] servers; 611 | public class Entry 612 | { 613 | public string server; 614 | } 615 | } 616 | } 617 | } 618 | -------------------------------------------------------------------------------- /BaiduOldDriver/NetDisk/PatientWebClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | class PatientWebClient : WebClient 5 | { 6 | public int Timeout = 300000; 7 | public PatientWebClient(int Timeout): base() 8 | { 9 | this.Timeout = Timeout; 10 | } 11 | public PatientWebClient() : base() 12 | { 13 | 14 | } 15 | protected override WebRequest GetWebRequest(Uri uri) 16 | { 17 | WebRequest w = base.GetWebRequest(uri); 18 | w.Timeout = Timeout; 19 | (w as HttpWebRequest).ReadWriteTimeout = Timeout; 20 | return w; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /BaiduOldDriver/NetDisk/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("NetDisk")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("NetDisk")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("74eca1bf-6508-417d-bc57-db00daeca618")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /BaiduOldDriver/NetDisk/Result.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace NetDisk 5 | { 6 | public class Result 7 | { 8 | public bool success; 9 | public Exception exception; 10 | } 11 | public class QuotaResult : Result 12 | { 13 | public int errno; 14 | public long total; 15 | public long free; 16 | public bool expire; 17 | public long used; 18 | } 19 | public class UserInfoResult : Result 20 | { 21 | public int errno; 22 | public Entry[] records; 23 | public class Entry 24 | { 25 | public string avatar_url; 26 | public string uname; 27 | public string priority_name; 28 | } 29 | } 30 | public class FileListResult : Result 31 | { 32 | public int errno; 33 | public Entry[] list; 34 | public class Entry 35 | { 36 | public int isdir; 37 | public string path; 38 | public string server_filename; 39 | public long size; 40 | } 41 | } 42 | public class ThumbnailResult : Result 43 | { 44 | public byte[] image; 45 | } 46 | public class GetDownloadResult : Result 47 | { 48 | public Entry[] urls; 49 | public class Entry 50 | { 51 | public int rank; 52 | public string url; 53 | } 54 | } 55 | public class FileOperationResult : Result 56 | { 57 | public int errno; 58 | public string path; 59 | } 60 | public class OfflineListResult : Result 61 | { 62 | public Entry[] tasks; 63 | public class Entry 64 | { 65 | public long create_time; 66 | public int od_type; 67 | public string save_path; 68 | public string source_url; 69 | public long task_id; 70 | public string task_name; 71 | public long file_size; 72 | public long finished_size; 73 | public int status; 74 | } 75 | } 76 | public class QueryLinkResult : Result 77 | { 78 | public Entry[] files; 79 | public string sha1; 80 | public class Entry 81 | { 82 | public string file_name; 83 | public long size; 84 | } 85 | } 86 | public class AddOfflineTaskResult : Result 87 | { 88 | public int rapid_download; 89 | public long task_id; 90 | } 91 | public class ShareResult : Result 92 | { 93 | public int errno; 94 | public long shareid; 95 | public string link; 96 | public string shorturl; 97 | } 98 | public class TransferResult : Result 99 | { 100 | public int errno; 101 | public Extra extra; 102 | public class Extra 103 | { 104 | public Entry[] list; 105 | public class Entry 106 | { 107 | public string from; 108 | public string to; 109 | } 110 | } 111 | } 112 | public class InitUploadResult : Result 113 | { 114 | public int[] block_list; 115 | public int errno; 116 | public string uploadid; 117 | } 118 | public class CommitUploadResult : Result 119 | { 120 | public long ctime; 121 | public int errno; 122 | public long fs_id; 123 | public int isdir; 124 | public string md5; 125 | public long mtime; 126 | public string name; 127 | public string path; 128 | public long size; 129 | } 130 | public class RapidUploadResult : Result 131 | { 132 | public int errno; 133 | public FileListResult.Entry info; 134 | } 135 | public class LoginResult : Result 136 | { 137 | public int errno; 138 | public Credential credential; 139 | } 140 | public class LoginCheckResult : Result 141 | { 142 | public bool needVCode; 143 | public string codeString; 144 | public string verifyCode; 145 | public byte[] image; 146 | public Cookie baiduid; 147 | public string ltoken; 148 | } 149 | public class GetUploadServersResult: Result 150 | { 151 | public string[] servers; 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /BaiduOldDriver/NetDisk/UploadHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Security.Cryptography; 5 | using System.Text; 6 | using DamienG.Security.Cryptography; 7 | 8 | namespace NetDisk 9 | { 10 | public static class UploadHelper 11 | { 12 | public static FileProperty GetFileProperty(string path) 13 | { 14 | var ret = new FileProperty() { path = path }; 15 | var info = new FileInfo(path); 16 | ret.size = info.Length; 17 | ret.mtime= (long)(info.LastAccessTime.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; 18 | ret.md5 = GetMD5HashFromFile(path); 19 | using (var fs = new FileStream(path, FileMode.Open)) 20 | { 21 | var md5 = new MD5CryptoServiceProvider(); 22 | var arr = new byte[4 * 1024 * 1024]; 23 | var len = fs.Read(arr, 0, 256 * 1024); 24 | ret.slice_md5 = ByteArrayToHexString(md5.ComputeHash(arr, 0, len)); 25 | fs.Seek(0, SeekOrigin.Begin); 26 | var blocks = new List(); 27 | while (true) 28 | { 29 | len = fs.Read(arr, 0, 4 * 1024 * 1024); 30 | if (len <= 0) break; 31 | blocks.Add(ByteArrayToHexString(md5.ComputeHash(arr, 0, len))); 32 | } 33 | ret.blocks = blocks.ToArray(); 34 | fs.Seek(0, SeekOrigin.Begin); 35 | var crc32 = new Crc32(); 36 | ret.crc32 = string.Empty; 37 | foreach (byte b in crc32.ComputeHash(fs)) ret.crc32 += b.ToString("x2").ToLower(); 38 | } 39 | return ret; 40 | } 41 | public static string GetMD5HashFromFile(string fileName) 42 | { 43 | using (var file = new FileStream(fileName, FileMode.Open)) 44 | { 45 | var md5 = new MD5CryptoServiceProvider(); 46 | var retVal = md5.ComputeHash(file); 47 | return ByteArrayToHexString(retVal); 48 | } 49 | } 50 | private static string ByteArrayToHexString(byte[] arr) 51 | { 52 | var sb = new StringBuilder(); 53 | for (int i = 0; i < arr.Length; i++) 54 | { 55 | sb.Append(arr[i].ToString("x2")); 56 | } 57 | return sb.ToString(); 58 | } 59 | } 60 | public class FileProperty 61 | { 62 | public string path; 63 | public long size; 64 | public string md5; 65 | public string slice_md5; 66 | public string crc32; 67 | public long mtime; 68 | public string[] blocks; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /BaiduOldDriver/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengw0048/BaiduOldDriver/06ac74ad424ee33bb5c4ba94c397c179da73b6b7/BaiduOldDriver/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /BaiduOldDriver/Test/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /BaiduOldDriver/Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("Test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Test")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("895c925b-58c5-42e5-b8b2-37a8ebb19823")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /BaiduOldDriver/Test/Test.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using NetDisk; 4 | using Downloader; 5 | using System.IO; 6 | using System.Threading; 7 | using System.Diagnostics; 8 | 9 | namespace Test 10 | { 11 | public class Test 12 | { 13 | static void CheckSuccess(Result result) 14 | { 15 | if (!result.success) 16 | { 17 | Console.WriteLine(result.exception); 18 | Console.ReadLine(); 19 | Environment.Exit(-1); 20 | } 21 | } 22 | static void Main(string[] args) 23 | { 24 | var username = "伪红学家"; 25 | var password = "******"; 26 | // Test login check 27 | var checkResult = Authentication.LoginCheck(username); 28 | CheckSuccess(checkResult); 29 | // Handle verify code 30 | if (checkResult.needVCode) 31 | { 32 | File.WriteAllBytes("vcode.png", checkResult.image); 33 | Console.WriteLine("Verification code required. Input the text in vcode.png."); 34 | try 35 | { 36 | System.Diagnostics.Process.Start("vcode.png"); 37 | } 38 | catch (Exception) { } 39 | checkResult.verifyCode = Console.ReadLine(); 40 | try 41 | { 42 | File.Delete("vcode.png"); 43 | } 44 | catch (Exception) { } 45 | } 46 | else Console.WriteLine("Verification code NOT required."); 47 | // Test login 48 | var loginResult = Authentication.Login(username, password, checkResult); 49 | CheckSuccess(loginResult); 50 | Console.WriteLine(loginResult.credential); 51 | Console.WriteLine("uid: " + loginResult.credential.uid); 52 | var credential = loginResult.credential; 53 | // Test get quota 54 | var quotaResult = Operation.GetQuota(credential); 55 | CheckSuccess(quotaResult); 56 | Console.WriteLine(quotaResult.used + "/" + quotaResult.total); 57 | // Test get user info 58 | var infoResult = Operation.GetUserInfo(credential); 59 | CheckSuccess(infoResult); 60 | Console.WriteLine(infoResult.records[0].uname + " " + infoResult.records[0].priority_name + " " + infoResult.records[0].avatar_url); 61 | // Test list file 62 | var fileListResult = Operation.GetFileList("/", credential); 63 | CheckSuccess(fileListResult); 64 | Console.WriteLine(string.Join("\r\n", fileListResult.list.Take(5).Select(e => e.path + " " + e.isdir + " " + e.size).ToArray())); 65 | // Test thumbnail 66 | var thumbnailResult = Operation.GetThumbnail("/1.mp4", credential); 67 | CheckSuccess(thumbnailResult); 68 | Console.WriteLine("Thumbnail " + thumbnailResult.image.Length + " bytes."); 69 | try 70 | { 71 | File.WriteAllBytes("thumb.jpg", thumbnailResult.image); 72 | var process = System.Diagnostics.Process.Start("thumb.jpg"); 73 | } 74 | catch (Exception) { } 75 | // Test rapid upload 76 | var rapidUploadResult = Operation.RapidUpload(UploadHelper.GetFileProperty("Z:\\Thunder9.0.14.358.exe"), "/t.exe", credential); 77 | CheckSuccess(rapidUploadResult); 78 | Console.WriteLine("Rapid: " + rapidUploadResult.info.path + " " + rapidUploadResult.info.size); 79 | // Test get upload servers 80 | var servers = Operation.GetUploadServers(credential); 81 | CheckSuccess(servers); 82 | Console.WriteLine("Servers: " + string.Join(" ", servers.servers)); 83 | // Test simple upload 84 | var simpleUploadResult = Operation.SimpleUpload("Z:\\1.rar", "/1.rar", credential, servers.servers[0]); 85 | CheckSuccess(simpleUploadResult); 86 | Console.WriteLine("Simple: " + simpleUploadResult.path + " " + simpleUploadResult.size); 87 | // Test chunked upload 88 | var chunkedUploadResult = Operation.ChunkedUpload("Z:\\2.rar", "/2.rar", credential); 89 | CheckSuccess(chunkedUploadResult); 90 | Console.WriteLine("Chunked: " + chunkedUploadResult.path + " " + chunkedUploadResult.size); 91 | // Test get download urls 92 | var downloadResult = Operation.GetDownload("/1.mp4", credential); 93 | CheckSuccess(downloadResult); 94 | Console.WriteLine("Download URL count = " + downloadResult.urls.Length + " " + downloadResult.urls[0].rank + " " + downloadResult.urls[0].url); 95 | // Test file operations 96 | var fileopResult = Operation.Copy("/1.mp4", "/", "2.mp4", credential); 97 | CheckSuccess(fileopResult); 98 | fileopResult = Operation.Move("/2.mp4", "/", "3.mp4", credential); 99 | CheckSuccess(fileopResult); 100 | fileopResult = Operation.Rename("/3.mp4", "4.mp4", credential); 101 | CheckSuccess(fileopResult); 102 | fileopResult = Operation.Delete("/4.mp4", credential); 103 | CheckSuccess(fileopResult); 104 | fileopResult = Operation.CreateFolder("/test", credential); 105 | CheckSuccess(fileopResult); 106 | Console.WriteLine("New folder name: " + fileopResult.path); 107 | // Test share 108 | var shareResult = Operation.Share(new[] { "/1.mp4" }, credential); 109 | CheckSuccess(shareResult); 110 | Console.WriteLine(shareResult.link + " " + shareResult.shorturl); 111 | shareResult = Operation.Share(new[] { "/1.mp4" }, credential, "8888"); 112 | CheckSuccess(shareResult); 113 | Console.WriteLine(shareResult.link + " " + shareResult.shorturl); 114 | // Test transfer shared files 115 | var transferResult = Operation.Transfer("http://pan.baidu.com/s/1hsfZ1TM", "/", credential, "1w9w"); 116 | CheckSuccess(transferResult); 117 | Console.WriteLine(transferResult.extra.list.Select(e => e.from + " " + e.to + "\r\n").ToString()); 118 | // Test offline 119 | var queryLinkResult = Operation.QueryLinkFiles("/downfile.torrent", credential); 120 | CheckSuccess(queryLinkResult); 121 | queryLinkResult.files.ToList().ForEach(f => Console.WriteLine(f.file_name + " " + f.size)); 122 | var addOfflineResult = Operation.AddOfflineTask("/downfile.torrent", "/", credential, new[] { 1 }, queryLinkResult.sha1); 123 | CheckSuccess(addOfflineResult); 124 | Console.WriteLine(addOfflineResult.task_id + " " + addOfflineResult.rapid_download); 125 | addOfflineResult = Operation.AddOfflineTask("http://www.baidu.com/", "/", credential); 126 | CheckSuccess(addOfflineResult); 127 | Console.WriteLine(addOfflineResult.task_id + " " + addOfflineResult.rapid_download); 128 | addOfflineResult = Operation.AddOfflineTask("magnet:?xt=urn:btih:eb748516ee0968422d9827a9991d28cbd4dc4f3f", "/", credential, new[] { 1, 2 }); 129 | CheckSuccess(addOfflineResult); 130 | Console.WriteLine(addOfflineResult.task_id + " " + addOfflineResult.rapid_download); 131 | addOfflineResult = Operation.AddOfflineTask("ed2k://|file|[柳井正与优衣库].蔡成平.文字版(ED2000.COM).epub|890525|90a92b89df20a8b2283fe3450f872590|h=oxrt54bznbtq5pr47dfmj4zfn5ctbvek|/", "/", credential); 132 | CheckSuccess(addOfflineResult); 133 | Console.WriteLine(addOfflineResult.task_id + " " + addOfflineResult.rapid_download); 134 | var offlineListResult = Operation.GetOfflineList(credential); 135 | CheckSuccess(offlineListResult); 136 | offlineListResult.tasks.ToList().ForEach(t => Console.WriteLine(t.status + " " + t.task_id + " " + t.task_name + " " + t.finished_size + "/" + t.file_size + " " + t.od_type)); 137 | Operation.ClearOfflineTask(credential); 138 | foreach (var item in offlineListResult.tasks) 139 | { 140 | Operation.CancelOfflineTask(item.task_id, credential); 141 | Operation.DeleteOfflineTask(item.task_id, credential); 142 | } 143 | offlineListResult = Operation.GetOfflineList(credential); 144 | CheckSuccess(offlineListResult); 145 | Debug.Assert(offlineListResult.tasks.Length == 0); 146 | Console.WriteLine("Offline list cleared."); 147 | // Test download 148 | var adapter = new BaiduAdapter() { credential = credential, path = "/1.mp4", size = fileListResult.list.First(e => e.path == "/1.mp4").size }; 149 | var task = new FileTask(adapter, "Z:\\1.mp4"); 150 | var st = new Stopwatch(); 151 | st.Start(); 152 | while (!task.IsCompleted()) 153 | { 154 | Console.WriteLine(task.GetDownloadedBytes()); 155 | foreach (var item in task.DownloadSources) 156 | { 157 | Console.WriteLine(" " + item.URL.Substring(0,20) + " " + item.GetDownloadedBytes()); 158 | } 159 | Thread.Sleep(1000); 160 | } 161 | st.Stop(); 162 | Console.WriteLine("Time taken: " + st.ElapsedMilliseconds / 1000); 163 | // Done 164 | Console.WriteLine("Success"); 165 | Console.ReadLine(); 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /BaiduOldDriver/Test/Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {895C925B-58C5-42E5-B8B2-37A8EBB19823} 8 | Exe 9 | Properties 10 | Test 11 | Test 12 | v4.5 13 | 512 14 | true 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | {799c6c77-79d2-48ea-a56d-912eec46b138} 56 | Downloader 57 | 58 | 59 | {74eca1bf-6508-417d-bc57-db00daeca618} 60 | NetDisk 61 | 62 | 63 | 64 | 71 | -------------------------------------------------------------------------------- /BaiduOldDriver/login_errno.txt: -------------------------------------------------------------------------------- 1 | ={ 2 | "-1":{ 3 | msg:'系统错误,请您稍后再试,问题反馈', 4 | field:"" 5 | }, 6 | 1:{ 7 | msg:"您输入的帐号格式不正确", 8 | field:"userName" 9 | }, 10 | 2:{ 11 | msg:"您输入的帐号不存在,可查看帮助立即注册", 12 | field:"userName" 13 | }, 14 | 3:{ 15 | msg:"验证码不存在或已过期,请重新输入", 16 | field:"" 17 | }, 18 | 4:{ 19 | msg:'您输入的帐号或密码有误,忘记密码?', 20 | field:"password" 21 | }, 22 | 5:{ 23 | msg:"", 24 | field:"" 25 | }, 26 | 6:{ 27 | msg:"您输入的验证码有误", 28 | field:"verifyCode" 29 | }, 30 | 7:{ 31 | msg:'密码错误,可以试试短信登录\r\n,或者找回密码', 32 | field:"password" 33 | }, 34 | 16:{ 35 | msg:'您的帐号因安全问题已被限制登录,问题反馈', 36 | field:"" 37 | }, 38 | 257:{ 39 | msg:"请输入验证码", 40 | field:"verifyCode" 41 | }, 42 | 100027:{ 43 | msg:"百度正在进行系统升级,暂时不能提供服务,敬请谅解", 44 | field:"" 45 | }, 46 | 120016:{ 47 | msg:"", 48 | field:"" 49 | }, 50 | 18:{ 51 | msg:"", 52 | field:"" 53 | }, 54 | 19:{ 55 | msg:"", 56 | field:"" 57 | }, 58 | 20:{ 59 | msg:"", 60 | field:"" 61 | }, 62 | 21:{ 63 | msg:"没有登录权限", 64 | field:"" 65 | }, 66 | 22:{ 67 | msg:"", 68 | field:"" 69 | }, 70 | 23:{ 71 | msg:"", 72 | field:"" 73 | }, 74 | 400031:{ 75 | msg:"请在弹出的窗口操作,或重新登录", 76 | field:"" 77 | }, 78 | 400032:{ 79 | msg:"", 80 | field:"" 81 | }, 82 | 400034:{ 83 | msg:"", 84 | field:"" 85 | }, 86 | 401007:{ 87 | msg:"您的手机号关联了其他帐号,请选择登录", 88 | field:"" 89 | }, 90 | 120021:{ 91 | msg:"登录失败,请在弹出的窗口操作,或重新登录", 92 | field:"" 93 | }, 94 | 500010:{ 95 | msg:"登录过于频繁,请24小时后再试", 96 | field:"" 97 | }, 98 | 200010:{ 99 | msg:"验证码不存在或已过期", 100 | field:"" 101 | }, 102 | 100005:{ 103 | msg:"系统错误,请您稍后再试", 104 | field:"" 105 | }, 106 | 120019:{ 107 | msg:"请在弹出的窗口操作,或重新登录", 108 | field:"userName" 109 | }, 110 | 110024:{ 111 | msg:'此帐号暂未激活,重发验证邮件', 112 | field:"" 113 | }, 114 | 100023:{ 115 | msg:'开启Cookie之后才能登录,如何开启?', 116 | field:"" 117 | }, 118 | 17:{ 119 | msg:"您的帐号已锁定,请解锁后登录", 120 | field:"userName" 121 | }, 122 | 400401:{ 123 | msg:"", 124 | field:"" 125 | }, 126 | 400037:{ 127 | msg:"", 128 | field:"" 129 | }, 130 | 50023:{ 131 | msg:"1个手机号30日内最多换绑3个账号", 132 | field:"" 133 | }, 134 | 50024:{ 135 | msg:"注册过于频繁,请稍候再试", 136 | field:"" 137 | }, 138 | 50025:{ 139 | msg:"注册过于频繁,请稍候再试;也可以通过上行短信的方式进行注册", 140 | field:"" 141 | }, 142 | 400414:{ 143 | msg:"您的帐号因为安全问题,暂时被冻结,详情请拨打电话010-59059588", 144 | field:"" 145 | }, 146 | 400415:{ 147 | msg:"您的帐号因为安全问题,暂时被冻结,详情请拨打电话010-59059588", 148 | field:"" 149 | } 150 | } --------------------------------------------------------------------------------