├── .gitignore ├── CHANGES ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── packaging └── upload.sh ├── shadowsocks-csharp.sln ├── shadowsocks-csharp ├── 3rd │ ├── SimpleJson.cs │ └── zxing │ │ ├── BarcodeFormat.cs │ │ ├── BaseLuminanceSource.cs │ │ ├── Binarizer.cs │ │ ├── BinaryBitmap.cs │ │ ├── BitmapLuminanceSource.cs │ │ ├── DecodeHintType.cs │ │ ├── EncodeHintType.cs │ │ ├── LuminanceSource.cs │ │ ├── Result.cs │ │ ├── ResultMetadataType.cs │ │ ├── ResultPoint.cs │ │ ├── ResultPointCallback.cs │ │ ├── WriterException.cs │ │ ├── common │ │ ├── BitArray.cs │ │ ├── BitMatrix.cs │ │ ├── BitSource.cs │ │ ├── DecoderResult.cs │ │ ├── DefaultGridSampler.cs │ │ ├── DetectorResult.cs │ │ ├── GlobalHistogramBinarizer.cs │ │ ├── GridSampler.cs │ │ ├── HybridBinarizer.cs │ │ ├── PerspectiveTransform.cs │ │ ├── StringUtils.cs │ │ ├── detector │ │ │ └── MathUtils.cs │ │ └── reedsolomon │ │ │ ├── GenericGF.cs │ │ │ ├── GenericGFPoly.cs │ │ │ ├── ReedSolomonDecoder.cs │ │ │ └── ReedSolomonEncoder.cs │ │ └── qrcode │ │ ├── QRCodeReader.cs │ │ ├── decoder │ │ ├── BitMatrixParser.cs │ │ ├── DataBlock.cs │ │ ├── DataMask.cs │ │ ├── DecodedBitStreamParser.cs │ │ ├── Decoder.cs │ │ ├── ErrorCorrectionLevel.cs │ │ ├── FormatInformation.cs │ │ ├── Mode.cs │ │ ├── QRCodeDecoderMetaData.cs │ │ └── Version.cs │ │ ├── detector │ │ ├── AlignmentPattern.cs │ │ ├── AlignmentPatternFinder.cs │ │ ├── Detector.cs │ │ ├── FinderPattern.cs │ │ ├── FinderPatternFinder.cs │ │ └── FinderPatternInfo.cs │ │ └── encoder │ │ ├── BlockPair.cs │ │ ├── ByteMatrix.cs │ │ ├── Encoder.cs │ │ ├── MaskUtil.cs │ │ ├── MatrixUtil.cs │ │ └── QRCode.cs ├── Controller │ ├── FileManager.cs │ ├── I18N.cs │ ├── Logging.cs │ ├── Service │ │ ├── AvailabilityStatistics.cs │ │ ├── GfwListUpdater.cs │ │ ├── Listener.cs │ │ ├── PACServer.cs │ │ ├── PolipoRunner.cs │ │ ├── PortForwarder.cs │ │ ├── TCPRelay.cs │ │ ├── UDPRelay.cs │ │ └── UpdateChecker.cs │ ├── ShadowsocksController.cs │ ├── Strategy │ │ ├── BalancingStrategy.cs │ │ ├── HighAvailabilityStrategy.cs │ │ ├── IStrategy.cs │ │ ├── SimplyChooseByStatisticsStrategy.cs │ │ └── StrategyManager.cs │ └── System │ │ ├── AutoStartup.cs │ │ └── SystemProxy.cs ├── Data │ ├── abp.js.gz │ ├── cn.txt │ ├── libsscrypto.dll.gz │ ├── mgwz.dll.gz │ ├── privoxy.exe.gz │ ├── privoxy_conf.txt │ ├── proxy.pac.txt.gz │ └── user-rule.txt ├── Encryption │ ├── EncryptorBase.cs │ ├── EncryptorFactory.cs │ ├── IEncryptor.cs │ ├── IVEncryptor.cs │ ├── PolarSSL.cs │ ├── PolarSSLEncryptor.cs │ ├── Sodium.cs │ ├── SodiumEncryptor.cs │ └── TableEncryptor.cs ├── Model │ ├── Configuration.cs │ └── Server.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Resources │ ├── ss16.png │ ├── ss20.png │ ├── ss24.png │ └── ssw128.png ├── Util │ └── Util.cs ├── View │ ├── ConfigForm.Designer.cs │ ├── ConfigForm.cs │ ├── ConfigForm.resx │ ├── LogForm.Designer.cs │ ├── LogForm.cs │ ├── LogForm.resx │ ├── MenuViewController.cs │ ├── QRCodeForm.Designer.cs │ ├── QRCodeForm.cs │ ├── QRCodeForm.resx │ └── QRCodeSplashForm.cs ├── app.config ├── app.manifest ├── shadowsocks-csharp.csproj └── shadowsocks.ico └── test ├── Properties └── AssemblyInfo.cs ├── UnitTest.cs └── test.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | Backup/ 2 | bin/ 3 | obj/ 4 | shadowsocks-csharp/shadowsocks-csharp.csproj.user 5 | TestResults 6 | *.suo 7 | 8 | -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | 2.5.6 2015-08-19 2 | - Add portable mode. Create shadowsocks_portable_mode.txt to use it 3 | - Support server reorder 4 | 5 | 2.5.5 2015-08-17 6 | - Fix crash when enabling Availability Statistics and some servers can not be resolved 7 | - Allow multiple instances 8 | - Other fixes 9 | 10 | 2.5.4 2015-08-16 11 | - Hide Privoxy icon 12 | 13 | 2.5.3 2015-08-16 14 | - Replace Polipo with Privoxy 15 | - Add Choose by Total Packet Loss 16 | 17 | 2.5.2 2015-08-04 18 | - Add log viewer 19 | 20 | 2.5.1 2015-07-26 21 | - Prevent HA from switching servers too frequently 22 | - Fix server settings can not be updated when using HA 23 | - Fix server port can't be 8123 24 | - Other minor fixes 25 | 26 | 2.5 2015-07-25 27 | - Support load balance 28 | - Support high availability 29 | 30 | 2.4 2015-07-11 31 | - Support UDP relay 32 | - Support online PAC 33 | - Migrate update checker to GitHub releases 34 | - Other fixes 35 | 36 | 2.3.1 2015-03-06 37 | - Support user rule 38 | 39 | 2.3 2015-01-25 40 | - Use the same port for every profile 41 | - Use the same port for HTTP/Socks5/PAC 42 | - Fix GFWList PAC compatibility issue with IE11 43 | - Encourage users to report to GFWList when no update found 44 | - Minor UI improvements 45 | 46 | 2.2.1 2015-01-18 47 | - Fix QR Code compatibility 48 | 49 | 2.2 2015-01-14 50 | - Support updating PAC from GFWList 51 | - Support adding server by scanning QR Code 52 | - Output timestamp in logs 53 | - Minor fixes 54 | 55 | 2.1.6 2015-01-02 56 | - Fix OPTIONS requests 57 | - Improve logs 58 | 59 | 2.1.5 2014-12-25 60 | - Fix QR Code compatibility with iOS 61 | - Only left button will trigger double click on tray icon 62 | 63 | 2.1.4 2014-12-20 64 | - Fix crash when remarks are too long 65 | 66 | 2.1.3 2014-12-20 67 | - Add Chinese Language 68 | - Fix some UI issues on Windows 8 69 | - Fix some UI issues on high DPI screens 70 | - Log bind error more friendly 71 | - Stability issues 72 | 73 | 2.1.2 2014-12-14 74 | - Fix sometimes Shadowsocks doesn't respond to requests 75 | 76 | 2.1.1 2014-12-14 77 | - Add global proxy option 78 | 79 | 2.1 2014-12-12 80 | - Add salsa20 and chacha20 support 81 | 82 | 2.0.11 2014-11-23 83 | - Fix a crash 84 | - Only switch the system proxy off if we have switched it on 85 | 86 | 2.0.10 2014-11-18 87 | - Minor fixes 88 | - Optimize code 89 | 90 | 2.0.9 2014-11-13 91 | - Fix startup path 92 | - Fix allowed port range for polipo 93 | 94 | 2.0.8 2014-11-12 95 | - Fix data corruption 96 | - Set proxy for PPPoE 97 | - Auto Startup Option 98 | - Support high DPI screens 99 | 100 | 2.0.7 2014-11-11 101 | - Use OpenSSL for now 102 | 103 | 2.0.6 2014-11-10 104 | - Minor bug fixes 105 | 106 | 2.0.5 2014-11-09 107 | - Fix QRCode size 108 | - Share over LAN option 109 | - Log to temp path instead 110 | 111 | 2.0.4 2014-11-09 112 | - Try to fix data corruption 113 | - Remove all configuration except x86 114 | 115 | 2.0.3 2014-11-08 116 | - Support QRCode generation 117 | - Fix compatibility issues with some Chrome version 118 | 119 | 2.0.2 2014-11-08 120 | - Add remarks 121 | - Fix error when polipo is killed 122 | 123 | 2.0.1 2014-11-08 124 | - Check already running 125 | 126 | 2.0 2014-11-08 127 | - Initial release 128 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | How to Contribute 2 | ================= 3 | 4 | Pull Requests 5 | ------------- 6 | 7 | 1. Pull requests are welcome. 8 | 2. Make sure to pass the unit tests. Write unit tests for new modules if 9 | needed. 10 | 11 | Issues 12 | ------ 13 | 14 | 1. Nobody has reported any bugs but posted a lot of questions in the last 15 | few months. So we're closing the issue tracker. 16 | 17 | 18 | [Troubleshooting]: https://github.com/clowwindy/shadowsocks/wiki/Troubleshooting 19 | [mailing lists]: https://groups.google.com/forum/#!forum/shadowsocks 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Shadowsocks for Windows 2 | ======================= 3 | 4 | [![Build Status]][Appveyor] 5 | 6 | [中文说明] 7 | 8 | #### Features 9 | 10 | 1. System proxy configuration 11 | 2. PAC mode and global mode 12 | 3. [GFWList] and user rules 13 | 4. Supports HTTP proxy 14 | 5. Supports server auto switching 15 | 6. Supports UDP relay (see Usage) 16 | 17 | #### Download 18 | 19 | Download the [latest release]. 20 | 21 | #### Basic 22 | 23 | 1. Find Shadowsocks icon in the notification tray 24 | 2. You can add multiple servers in servers menu 25 | 3. Select `Enable System Proxy` menu to enable system proxy. Please disable other 26 | proxy addons in your browser, or set them to use system proxy 27 | 4. You can also configure your browser proxy manually if you don't want to enable 28 | system proxy. Set Socks5 or HTTP proxy to 127.0.0.1:1080. You can change this 29 | port in `Servers -> Edit Servers` 30 | 31 | #### PAC 32 | 33 | 1. You can change PAC rules by editing the PAC file. When you save the PAC file 34 | with any editor, Shadowsocks will notify browsers about the change automatically 35 | 2. You can also update PAC file from [GFWList] (maintained by 3rd party) 36 | 3. You can also use online PAC URL 37 | 38 | #### Server Auto Switching 39 | 40 | 1. Load balance: choosing server randomly 41 | 2. High availability: choosing the best server (low latency and packet loss) 42 | 3. Choose By Total Package Loss: ping and choose. Please also enable 43 | `Availability Statistics` in the menu if you want to use this 44 | 4. Write your own strategy by implement IStrategy interface and send us a pull request! 45 | 46 | #### UDP 47 | 48 | For UDP, you need to use SocksCap or ProxyCap to force programs you want 49 | to be proxied to tunnel over Shadowsocks 50 | 51 | #### Multiple Instances 52 | 53 | If you want to manage multiple servers using other tools like SwitchyOmega, 54 | you can start multiple Shadowsocks instances. To avoid configuration conflicts, 55 | copy Shadowsocks to a new directory and choose a different local port. 56 | 57 | Also, make sure to use `SOCKS5` proxy in SwitchyOmega, since we have only 58 | one HTTP proxy instance. 59 | 60 | #### Server Configuration 61 | 62 | Please visit [Servers] for more information. 63 | 64 | #### Portable Mode 65 | 66 | If you want to put all temporary files into shadowsocks/temp folder instead of 67 | system temp folder, create a `shadowsocks_portable_mode.txt` into shadowsocks folder. 68 | 69 | #### Develop 70 | 71 | Visual Studio 2015 is required. 72 | 73 | #### License 74 | 75 | GPLv3 76 | 77 | 78 | [Appveyor]: https://ci.appveyor.com/project/clowwindy/shadowsocks-csharp 79 | [Build Status]: https://ci.appveyor.com/api/projects/status/gknc8l1lxy423ehv/branch/master 80 | [latest release]: https://github.com/shadowsocks/shadowsocks-csharp/releases 81 | [GFWList]: https://github.com/gfwlist/gfwlist 82 | [Servers]: https://github.com/shadowsocks/shadowsocks/wiki/Ports-and-Clients#linux--server-side 83 | [中文说明]: https://github.com/shadowsocks/shadowsocks-windows/wiki/Shadowsocks-Windows-%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E 84 | -------------------------------------------------------------------------------- /packaging/upload.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | version=$1 4 | 5 | rsync --progress -e ssh shadowsocks-csharp/bin/x86/Release/Shadowsocks-win-dotnet4.0-$1.zip frs.sourceforge.net:/home/frs/project/shadowsocksgui/dist/ 6 | rsync --progress -e ssh shadowsocks-csharp/bin/x86/Release/Shadowsocks-win-$1.zip frs.sourceforge.net:/home/frs/project/shadowsocksgui/dist/ 7 | -------------------------------------------------------------------------------- /shadowsocks-csharp.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Express 2012 for Windows Desktop 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "shadowsocks-csharp", "shadowsocks-csharp\shadowsocks-csharp.csproj", "{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test\test.csproj", "{45913187-0685-4903-B250-DCEF0479CD86}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062} = {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062} 9 | EndProjectSection 10 | EndProject 11 | Global 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Debug|x86 = Debug|x86 14 | Release|x86 = Release|x86 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.ActiveCfg = Debug|x86 18 | {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Build.0 = Debug|x86 19 | {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Deploy.0 = Debug|x86 20 | {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.ActiveCfg = Release|x86 21 | {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.Build.0 = Release|x86 22 | {45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.ActiveCfg = Debug|x86 23 | {45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.Build.0 = Debug|x86 24 | {45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.ActiveCfg = Release|x86 25 | {45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.Build.0 = Release|x86 26 | EndGlobalSection 27 | GlobalSection(SolutionProperties) = preSolution 28 | HideSolutionNode = FALSE 29 | EndGlobalSection 30 | EndGlobal 31 | -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/BarcodeFormat.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | namespace ZXing 18 | { 19 | /// 20 | /// Enumerates barcode formats known to this package. 21 | /// 22 | /// Sean Owen 23 | [System.Flags] 24 | public enum BarcodeFormat 25 | { 26 | /// Aztec 2D barcode format. 27 | AZTEC = 1, 28 | 29 | /// CODABAR 1D format. 30 | CODABAR = 2, 31 | 32 | /// Code 39 1D format. 33 | CODE_39 = 4, 34 | 35 | /// Code 93 1D format. 36 | CODE_93 = 8, 37 | 38 | /// Code 128 1D format. 39 | CODE_128 = 16, 40 | 41 | /// Data Matrix 2D barcode format. 42 | DATA_MATRIX = 32, 43 | 44 | /// EAN-8 1D format. 45 | EAN_8 = 64, 46 | 47 | /// EAN-13 1D format. 48 | EAN_13 = 128, 49 | 50 | /// ITF (Interleaved Two of Five) 1D format. 51 | ITF = 256, 52 | 53 | /// MaxiCode 2D barcode format. 54 | MAXICODE = 512, 55 | 56 | /// PDF417 format. 57 | PDF_417 = 1024, 58 | 59 | /// QR Code 2D barcode format. 60 | QR_CODE = 2048, 61 | 62 | /// RSS 14 63 | RSS_14 = 4096, 64 | 65 | /// RSS EXPANDED 66 | RSS_EXPANDED = 8192, 67 | 68 | /// UPC-A 1D format. 69 | UPC_A = 16384, 70 | 71 | /// UPC-E 1D format. 72 | UPC_E = 32768, 73 | 74 | /// UPC/EAN extension format. Not a stand-alone format. 75 | UPC_EAN_EXTENSION = 65536, 76 | 77 | /// MSI 78 | MSI = 131072, 79 | 80 | /// Plessey 81 | PLESSEY = 262144, 82 | 83 | /// 84 | /// UPC_A | UPC_E | EAN_13 | EAN_8 | CODABAR | CODE_39 | CODE_93 | CODE_128 | ITF | RSS_14 | RSS_EXPANDED 85 | /// without MSI (to many false-positives) 86 | /// 87 | All_1D = UPC_A | UPC_E | EAN_13 | EAN_8 | CODABAR | CODE_39 | CODE_93 | CODE_128 | ITF | RSS_14 | RSS_EXPANDED 88 | } 89 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/Binarizer.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | using System; 18 | 19 | using ZXing.Common; 20 | 21 | namespace ZXing 22 | { 23 | /// This class hierarchy provides a set of methods to convert luminance data to 1 bit data. 24 | /// It allows the algorithm to vary polymorphically, for example allowing a very expensive 25 | /// thresholding technique for servers and a fast one for mobile. It also permits the implementation 26 | /// to vary, e.g. a JNI version for Android and a Java fallback version for other platforms. 27 | /// 28 | /// dswitkin@google.com (Daniel Switkin) 29 | /// 30 | public abstract class Binarizer 31 | { 32 | private readonly LuminanceSource source; 33 | 34 | /// 35 | /// Initializes a new instance of the class. 36 | /// 37 | /// The source. 38 | protected internal Binarizer(LuminanceSource source) 39 | { 40 | if (source == null) 41 | { 42 | throw new ArgumentException("Source must be non-null."); 43 | } 44 | this.source = source; 45 | } 46 | 47 | /// 48 | /// Gets the luminance source object. 49 | /// 50 | virtual public LuminanceSource LuminanceSource 51 | { 52 | get 53 | { 54 | return source; 55 | } 56 | } 57 | 58 | /// Converts one row of luminance data to 1 bit data. May actually do the conversion, or return 59 | /// cached data. Callers should assume this method is expensive and call it as seldom as possible. 60 | /// This method is intended for decoding 1D barcodes and may choose to apply sharpening. 61 | /// For callers which only examine one row of pixels at a time, the same BitArray should be reused 62 | /// and passed in with each call for performance. However it is legal to keep more than one row 63 | /// at a time if needed. 64 | /// 65 | /// The row to fetch, 0 <= y < bitmap height. 66 | /// An optional preallocated array. If null or too small, it will be ignored. 67 | /// If used, the Binarizer will call BitArray.clear(). Always use the returned object. 68 | /// 69 | /// The array of bits for this row (true means black). 70 | public abstract BitArray getBlackRow(int y, BitArray row); 71 | 72 | /// Converts a 2D array of luminance data to 1 bit data. As above, assume this method is expensive 73 | /// and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or 74 | /// may not apply sharpening. Therefore, a row from this matrix may not be identical to one 75 | /// fetched using getBlackRow(), so don't mix and match between them. 76 | /// 77 | /// The 2D array of bits for the image (true means black). 78 | public abstract BitMatrix BlackMatrix { get; } 79 | 80 | /// Creates a new object with the same type as this Binarizer implementation, but with pristine 81 | /// state. This is needed because Binarizer implementations may be stateful, e.g. keeping a cache 82 | /// of 1 bit data. See Effective Java for why we can't use Java's clone() method. 83 | /// 84 | /// The LuminanceSource this Binarizer will operate on. 85 | /// A new concrete Binarizer implementation object. 86 | public abstract Binarizer createBinarizer(LuminanceSource source); 87 | 88 | /// 89 | /// Gets the width of the luminance source object. 90 | /// 91 | public int Width 92 | { 93 | get { return source.Width; } 94 | } 95 | 96 | /// 97 | /// Gets the height of the luminance source object. 98 | /// 99 | public int Height 100 | { 101 | get { return source.Height; } 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/DecodeHintType.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | 20 | namespace ZXing 21 | { 22 | /// 23 | /// Encapsulates a type of hint that a caller may pass to a barcode reader to help it 24 | /// more quickly or accurately decode it. It is up to implementations to decide what, 25 | /// if anything, to do with the information that is supplied. 26 | /// 27 | /// 28 | /// Sean Owen 29 | /// dswitkin@google.com (Daniel Switkin) 30 | public enum DecodeHintType 31 | { 32 | /// 33 | /// Unspecified, application-specific hint. Maps to an unspecified . 34 | /// 35 | OTHER, 36 | 37 | /// 38 | /// Image is a pure monochrome image of a barcode. Doesn't matter what it maps to; 39 | /// use = true. 40 | /// 41 | PURE_BARCODE, 42 | 43 | /// 44 | /// Image is known to be of one of a few possible formats. 45 | /// Maps to a of s. 46 | /// 47 | POSSIBLE_FORMATS, 48 | 49 | /// 50 | /// Spend more time to try to find a barcode; optimize for accuracy, not speed. 51 | /// Doesn't matter what it maps to; use = true. 52 | /// 53 | TRY_HARDER, 54 | 55 | /// 56 | /// Specifies what character encoding to use when decoding, where applicable (type String) 57 | /// 58 | CHARACTER_SET, 59 | 60 | /// 61 | /// Allowed lengths of encoded data -- reject anything else. Maps to an int[]. 62 | /// 63 | ALLOWED_LENGTHS, 64 | 65 | /// 66 | /// Assume Code 39 codes employ a check digit. Maps to . 67 | /// 68 | ASSUME_CODE_39_CHECK_DIGIT, 69 | 70 | /// 71 | /// The caller needs to be notified via callback when a possible 72 | /// is found. Maps to a . 73 | /// 74 | NEED_RESULT_POINT_CALLBACK, 75 | 76 | /// 77 | /// Assume MSI codes employ a check digit. Maps to . 78 | /// 79 | ASSUME_MSI_CHECK_DIGIT, 80 | 81 | /// 82 | /// if Code39 could be detected try to use extended mode for full ASCII character set 83 | /// Maps to . 84 | /// 85 | USE_CODE_39_EXTENDED_MODE, 86 | 87 | /// 88 | /// Don't fail if a Code39 is detected but can't be decoded in extended mode. 89 | /// Return the raw Code39 result instead. Maps to . 90 | /// 91 | RELAXED_CODE_39_EXTENDED_MODE, 92 | 93 | /// 94 | /// 1D readers supporting rotation with TRY_HARDER enabled. 95 | /// But BarcodeReader class can do auto-rotating for 1D and 2D codes. 96 | /// Enabling that option prevents 1D readers doing double rotation. 97 | /// BarcodeReader enables that option automatically if "global" auto-rotation is enabled. 98 | /// Maps to . 99 | /// 100 | TRY_HARDER_WITHOUT_ROTATION, 101 | 102 | /// 103 | /// Assume the barcode is being processed as a GS1 barcode, and modify behavior as needed. 104 | /// For example this affects FNC1 handling for Code 128 (aka GS1-128). Doesn't matter what it maps to; 105 | /// use . 106 | /// 107 | ASSUME_GS1, 108 | 109 | /// 110 | /// If true, return the start and end digits in a Codabar barcode instead of stripping them. They 111 | /// are alpha, whereas the rest are numeric. By default, they are stripped, but this causes them 112 | /// to not be. Doesn't matter what it maps to; use . 113 | /// 114 | RETURN_CODABAR_START_END, 115 | 116 | /// 117 | /// Allowed extension lengths for EAN or UPC barcodes. Other formats will ignore this. 118 | /// Maps to an of the allowed extension lengths, for example [2], [5], or [2, 5]. 119 | /// If it is optional to have an extension, do not set this hint. If this is set, 120 | /// and a UPC or EAN barcode is found but an extension is not, then no result will be returned 121 | /// at all. 122 | /// 123 | ALLOWED_EAN_EXTENSIONS 124 | } 125 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/EncodeHintType.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | namespace ZXing 18 | { 19 | /// 20 | /// These are a set of hints that you may pass to Writers to specify their behavior. 21 | /// 22 | /// dswitkin@google.com (Daniel Switkin) 23 | public enum EncodeHintType 24 | { 25 | /// 26 | /// Specifies the width of the barcode image 27 | /// type: 28 | /// 29 | WIDTH, 30 | 31 | /// 32 | /// Specifies the height of the barcode image 33 | /// type: 34 | /// 35 | HEIGHT, 36 | 37 | /// 38 | /// Don't put the content string into the output image. 39 | /// type: 40 | /// 41 | PURE_BARCODE, 42 | 43 | /// 44 | /// Specifies what degree of error correction to use, for example in QR Codes. 45 | /// Type depends on the encoder. For example for QR codes it's type 46 | /// 47 | /// For Aztec it is of type , representing the minimal percentage of error correction words. 48 | /// Note: an Aztec symbol should have a minimum of 25% EC words. 49 | /// For PDF417 it is of type or (between 0 and 8), 50 | /// 51 | ERROR_CORRECTION, 52 | 53 | /// 54 | /// Specifies what character encoding to use where applicable. 55 | /// type: 56 | /// 57 | CHARACTER_SET, 58 | 59 | /// 60 | /// Specifies margin, in pixels, to use when generating the barcode. The meaning can vary 61 | /// by format; for example it controls margin before and after the barcode horizontally for 62 | /// most 1D formats. 63 | /// type: 64 | /// 65 | MARGIN, 66 | 67 | /// 68 | /// Specifies whether to use compact mode for PDF417. 69 | /// type: 70 | /// 71 | PDF417_COMPACT, 72 | 73 | /// 74 | /// Specifies what compaction mode to use for PDF417. 75 | /// type: 76 | /// 77 | PDF417_COMPACTION, 78 | 79 | /// 80 | /// Specifies the minimum and maximum number of rows and columns for PDF417. 81 | /// type: 82 | /// 83 | PDF417_DIMENSIONS, 84 | 85 | /// 86 | /// Don't append ECI segment. 87 | /// That is against the specification of QR Code but some 88 | /// readers have problems if the charset is switched from 89 | /// ISO-8859-1 (default) to UTF-8 with the necessary ECI segment. 90 | /// If you set the property to true you can use UTF-8 encoding 91 | /// and the ECI segment is omitted. 92 | /// type: 93 | /// 94 | DISABLE_ECI, 95 | 96 | /// 97 | /// Specifies the matrix shape for Data Matrix (type ) 98 | /// 99 | DATA_MATRIX_SHAPE, 100 | 101 | /// 102 | /// Specifies a minimum barcode size (type ). Only applicable to Data Matrix now. 103 | /// 104 | MIN_SIZE, 105 | 106 | /// 107 | /// Specifies a maximum barcode size (type ). Only applicable to Data Matrix now. 108 | /// 109 | MAX_SIZE, 110 | 111 | /// 112 | /// if true, don't switch to codeset C for numbers 113 | /// 114 | CODE128_FORCE_CODESET_B, 115 | 116 | /// 117 | /// Specifies the default encodation for Data Matrix (type ) 118 | /// Make sure that the content fits into the encodation value, otherwise there will be an exception thrown. 119 | /// standard value: Encodation.ASCII 120 | /// 121 | DATA_MATRIX_DEFAULT_ENCODATION, 122 | 123 | /// 124 | /// Specifies the required number of layers for an Aztec code: 125 | /// a negative number (-1, -2, -3, -4) specifies a compact Aztec code 126 | /// 0 indicates to use the minimum number of layers (the default) 127 | /// a positive number (1, 2, .. 32) specifies a normal (non-compact) Aztec code 128 | /// 129 | AZTEC_LAYERS, 130 | } 131 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/Result.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | 20 | namespace ZXing 21 | { 22 | /// 23 | /// Encapsulates the result of decoding a barcode within an image. 24 | /// 25 | public sealed class Result 26 | { 27 | /// raw text encoded by the barcode, if applicable, otherwise null 28 | public String Text { get; private set; } 29 | 30 | /// raw bytes encoded by the barcode, if applicable, otherwise null 31 | public byte[] RawBytes { get; private set; } 32 | 33 | /// 34 | /// points related to the barcode in the image. These are typically points 35 | /// identifying finder patterns or the corners of the barcode. The exact meaning is 36 | /// specific to the type of barcode that was decoded. 37 | /// 38 | public ResultPoint[] ResultPoints { get; private set; } 39 | 40 | /// {@link BarcodeFormat} representing the format of the barcode that was decoded 41 | public BarcodeFormat BarcodeFormat { get; private set; } 42 | 43 | /// 44 | /// {@link Hashtable} mapping {@link ResultMetadataType} keys to values. May be 45 | /// null. This contains optional metadata about what was detected about the barcode, 46 | /// like orientation. 47 | /// 48 | public IDictionary ResultMetadata { get; private set; } 49 | 50 | /// 51 | /// Gets the timestamp. 52 | /// 53 | public long Timestamp { get; private set; } 54 | 55 | /// 56 | /// Initializes a new instance of the class. 57 | /// 58 | /// The text. 59 | /// The raw bytes. 60 | /// The result points. 61 | /// The format. 62 | public Result(String text, 63 | byte[] rawBytes, 64 | ResultPoint[] resultPoints, 65 | BarcodeFormat format) 66 | : this(text, rawBytes, resultPoints, format, DateTime.Now.Ticks) 67 | { 68 | } 69 | 70 | /// 71 | /// Initializes a new instance of the class. 72 | /// 73 | /// The text. 74 | /// The raw bytes. 75 | /// The result points. 76 | /// The format. 77 | /// The timestamp. 78 | public Result(String text, byte[] rawBytes, ResultPoint[] resultPoints, BarcodeFormat format, long timestamp) 79 | { 80 | if (text == null && rawBytes == null) 81 | { 82 | throw new ArgumentException("Text and bytes are null"); 83 | } 84 | Text = text; 85 | RawBytes = rawBytes; 86 | ResultPoints = resultPoints; 87 | BarcodeFormat = format; 88 | ResultMetadata = null; 89 | Timestamp = timestamp; 90 | } 91 | 92 | /// 93 | /// Adds one metadata to the result 94 | /// 95 | /// The type. 96 | /// The value. 97 | public void putMetadata(ResultMetadataType type, Object value) 98 | { 99 | if (ResultMetadata == null) 100 | { 101 | ResultMetadata = new Dictionary(); 102 | } 103 | ResultMetadata[type] = value; 104 | } 105 | 106 | /// 107 | /// Adds a list of metadata to the result 108 | /// 109 | /// The metadata. 110 | public void putAllMetadata(IDictionary metadata) 111 | { 112 | if (metadata != null) 113 | { 114 | if (ResultMetadata == null) 115 | { 116 | ResultMetadata = metadata; 117 | } 118 | else 119 | { 120 | foreach (var entry in metadata) 121 | ResultMetadata[entry.Key] = entry.Value; 122 | } 123 | } 124 | } 125 | 126 | /// 127 | /// Adds the result points. 128 | /// 129 | /// The new points. 130 | public void addResultPoints(ResultPoint[] newPoints) 131 | { 132 | var oldPoints = ResultPoints; 133 | if (oldPoints == null) 134 | { 135 | ResultPoints = newPoints; 136 | } 137 | else if (newPoints != null && newPoints.Length > 0) 138 | { 139 | var allPoints = new ResultPoint[oldPoints.Length + newPoints.Length]; 140 | Array.Copy(oldPoints, 0, allPoints, 0, oldPoints.Length); 141 | Array.Copy(newPoints, 0, allPoints, oldPoints.Length, newPoints.Length); 142 | ResultPoints = allPoints; 143 | } 144 | } 145 | 146 | /// 147 | /// Returns a that represents this instance. 148 | /// 149 | /// 150 | /// A that represents this instance. 151 | /// 152 | public override String ToString() 153 | { 154 | if (Text == null) 155 | { 156 | return "[" + RawBytes.Length + " bytes]"; 157 | } 158 | return Text; 159 | } 160 | } 161 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/ResultMetadataType.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | namespace ZXing 18 | { 19 | /// 20 | /// Represents some type of metadata about the result of the decoding that the decoder 21 | /// wishes to communicate back to the caller. 22 | /// 23 | /// Sean Owen 24 | public enum ResultMetadataType 25 | { 26 | /// 27 | /// Unspecified, application-specific metadata. Maps to an unspecified {@link Object}. 28 | /// 29 | OTHER, 30 | 31 | /// 32 | /// Denotes the likely approximate orientation of the barcode in the image. This value 33 | /// is given as degrees rotated clockwise from the normal, upright orientation. 34 | /// For example a 1D barcode which was found by reading top-to-bottom would be 35 | /// said to have orientation "90". This key maps to an {@link Integer} whose 36 | /// value is in the range [0,360). 37 | /// 38 | ORIENTATION, 39 | 40 | /// 41 | ///

2D barcode formats typically encode text, but allow for a sort of 'byte mode' 42 | /// which is sometimes used to encode binary data. While {@link Result} makes available 43 | /// the complete raw bytes in the barcode for these formats, it does not offer the bytes 44 | /// from the byte segments alone.

45 | ///

This maps to a {@link java.util.List} of byte arrays corresponding to the 46 | /// raw bytes in the byte segments in the barcode, in order.

47 | ///
48 | BYTE_SEGMENTS, 49 | 50 | /// 51 | /// Error correction level used, if applicable. The value type depends on the 52 | /// format, but is typically a String. 53 | /// 54 | ERROR_CORRECTION_LEVEL, 55 | 56 | /// 57 | /// For some periodicals, indicates the issue number as an {@link Integer}. 58 | /// 59 | ISSUE_NUMBER, 60 | 61 | /// 62 | /// For some products, indicates the suggested retail price in the barcode as a 63 | /// formatted {@link String}. 64 | /// 65 | SUGGESTED_PRICE, 66 | 67 | /// 68 | /// For some products, the possible country of manufacture as a {@link String} denoting the 69 | /// ISO country code. Some map to multiple possible countries, like "US/CA". 70 | /// 71 | POSSIBLE_COUNTRY, 72 | 73 | /// 74 | /// For some products, the extension text 75 | /// 76 | UPC_EAN_EXTENSION, 77 | 78 | /// 79 | /// If the code format supports structured append and 80 | /// the current scanned code is part of one then the 81 | /// sequence number is given with it. 82 | /// 83 | STRUCTURED_APPEND_SEQUENCE, 84 | 85 | /// 86 | /// If the code format supports structured append and 87 | /// the current scanned code is part of one then the 88 | /// parity is given with it. 89 | /// 90 | STRUCTURED_APPEND_PARITY, 91 | 92 | /// 93 | /// PDF417-specific metadata 94 | /// 95 | PDF417_EXTRA_METADATA, 96 | 97 | /// 98 | /// Aztec-specific metadata 99 | /// 100 | AZTEC_EXTRA_METADATA 101 | } 102 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/ResultPointCallback.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | namespace ZXing 18 | { 19 | /// Callback which is invoked when a possible result point (significant 20 | /// point in the barcode image such as a corner) is found. 21 | /// 22 | /// 23 | /// 24 | /// 25 | public delegate void ResultPointCallback(ResultPoint point); 26 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/WriterException.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | using System; 18 | 19 | namespace ZXing 20 | { 21 | /// 22 | /// A base class which covers the range of exceptions which may occur when encoding a barcode using 23 | /// the Writer framework. 24 | /// 25 | /// dswitkin@google.com (Daniel Switkin) 26 | [Serializable] 27 | public sealed class WriterException : Exception 28 | { 29 | /// 30 | /// Initializes a new instance of the class. 31 | /// 32 | public WriterException() 33 | { 34 | } 35 | 36 | /// 37 | /// Initializes a new instance of the class. 38 | /// 39 | /// The message. 40 | public WriterException(String message) 41 | :base(message) 42 | { 43 | } 44 | 45 | /// 46 | /// Initializes a new instance of the class. 47 | /// 48 | /// The message. 49 | /// The inner exc. 50 | public WriterException(String message, Exception innerExc) 51 | : base(message, innerExc) 52 | { 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/common/BitSource.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | using System; 18 | 19 | namespace ZXing.Common 20 | { 21 | ///

This provides an easy abstraction to read bits at a time from a sequence of bytes, where the 22 | /// number of bits read is not often a multiple of 8.

23 | /// 24 | ///

This class is thread-safe but not reentrant. Unless the caller modifies the bytes array 25 | /// it passed in, in which case all bets are off.

26 | /// 27 | ///
28 | /// Sean Owen 29 | /// 30 | /// www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source 31 | /// 32 | public sealed class BitSource 33 | { 34 | private readonly byte[] bytes; 35 | private int byteOffset; 36 | private int bitOffset; 37 | 38 | /// bytes from which this will read bits. Bits will be read from the first byte first. 39 | /// Bits are read within a byte from most-significant to least-significant bit. 40 | /// 41 | public BitSource(byte[] bytes) 42 | { 43 | this.bytes = bytes; 44 | } 45 | 46 | /// 47 | /// index of next bit in current byte which would be read by the next call to {@link #readBits(int)}. 48 | /// 49 | public int BitOffset 50 | { 51 | get { return bitOffset; } 52 | } 53 | 54 | /// 55 | /// index of next byte in input byte array which would be read by the next call to {@link #readBits(int)}. 56 | /// 57 | public int ByteOffset 58 | { 59 | get { return byteOffset; } 60 | } 61 | 62 | /// number of bits to read 63 | /// 64 | /// int representing the bits read. The bits will appear as the least-significant 65 | /// bits of the int 66 | /// 67 | /// if numBits isn't in [1,32] or more than is available 68 | public int readBits(int numBits) 69 | { 70 | if (numBits < 1 || numBits > 32 || numBits > available()) 71 | { 72 | throw new ArgumentException(numBits.ToString(), "numBits"); 73 | } 74 | 75 | int result = 0; 76 | 77 | // First, read remainder from current byte 78 | if (bitOffset > 0) 79 | { 80 | int bitsLeft = 8 - bitOffset; 81 | int toRead = numBits < bitsLeft ? numBits : bitsLeft; 82 | int bitsToNotRead = bitsLeft - toRead; 83 | int mask = (0xFF >> (8 - toRead)) << bitsToNotRead; 84 | result = (bytes[byteOffset] & mask) >> bitsToNotRead; 85 | numBits -= toRead; 86 | bitOffset += toRead; 87 | if (bitOffset == 8) 88 | { 89 | bitOffset = 0; 90 | byteOffset++; 91 | } 92 | } 93 | 94 | // Next read whole bytes 95 | if (numBits > 0) 96 | { 97 | while (numBits >= 8) 98 | { 99 | result = (result << 8) | (bytes[byteOffset] & 0xFF); 100 | byteOffset++; 101 | numBits -= 8; 102 | } 103 | 104 | // Finally read a partial byte 105 | if (numBits > 0) 106 | { 107 | int bitsToNotRead = 8 - numBits; 108 | int mask = (0xFF >> bitsToNotRead) << bitsToNotRead; 109 | result = (result << numBits) | ((bytes[byteOffset] & mask) >> bitsToNotRead); 110 | bitOffset += numBits; 111 | } 112 | } 113 | 114 | return result; 115 | } 116 | 117 | /// number of bits that can be read successfully 118 | /// 119 | public int available() 120 | { 121 | return 8 * (bytes.Length - byteOffset) - bitOffset; 122 | } 123 | } 124 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/common/DecoderResult.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | 20 | namespace ZXing.Common 21 | { 22 | /// 23 | /// Encapsulates the result of decoding a matrix of bits. This typically 24 | /// applies to 2D barcode formats. For now it contains the raw bytes obtained, 25 | /// as well as a String interpretation of those bytes, if applicable. 26 | /// Sean Owen 27 | /// 28 | public sealed class DecoderResult 29 | { 30 | public byte[] RawBytes { get; private set; } 31 | 32 | public String Text { get; private set; } 33 | 34 | public IList ByteSegments { get; private set; } 35 | 36 | public String ECLevel { get; private set; } 37 | 38 | public bool StructuredAppend 39 | { 40 | get { return StructuredAppendParity >= 0 && StructuredAppendSequenceNumber >= 0; } 41 | } 42 | 43 | public int ErrorsCorrected { get; set; } 44 | 45 | public int StructuredAppendSequenceNumber { get; private set; } 46 | 47 | public int Erasures { get; set; } 48 | 49 | public int StructuredAppendParity { get; private set; } 50 | 51 | /// 52 | /// Miscellanseous data value for the various decoders 53 | /// 54 | /// The other. 55 | public object Other { get; set; } 56 | 57 | public DecoderResult(byte[] rawBytes, String text, IList byteSegments, String ecLevel) 58 | : this(rawBytes, text, byteSegments, ecLevel, -1, -1) 59 | { 60 | } 61 | 62 | public DecoderResult(byte[] rawBytes, String text, IList byteSegments, String ecLevel, int saSequence, int saParity) 63 | { 64 | if (rawBytes == null && text == null) 65 | { 66 | throw new ArgumentException(); 67 | } 68 | RawBytes = rawBytes; 69 | Text = text; 70 | ByteSegments = byteSegments; 71 | ECLevel = ecLevel; 72 | StructuredAppendParity = saParity; 73 | StructuredAppendSequenceNumber = saSequence; 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/common/DefaultGridSampler.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | using System; 17 | 18 | namespace ZXing.Common 19 | { 20 | 21 | /// Sean Owen 22 | /// 23 | /// www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source 24 | /// 25 | public sealed class DefaultGridSampler : GridSampler 26 | { 27 | public override BitMatrix sampleGrid(BitMatrix image, int dimensionX, int dimensionY, float p1ToX, float p1ToY, float p2ToX, float p2ToY, float p3ToX, float p3ToY, float p4ToX, float p4ToY, float p1FromX, float p1FromY, float p2FromX, float p2FromY, float p3FromX, float p3FromY, float p4FromX, float p4FromY) 28 | { 29 | PerspectiveTransform transform = PerspectiveTransform.quadrilateralToQuadrilateral( 30 | p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY, 31 | p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY); 32 | return sampleGrid(image, dimensionX, dimensionY, transform); 33 | } 34 | 35 | public override BitMatrix sampleGrid(BitMatrix image, int dimensionX, int dimensionY, PerspectiveTransform transform) 36 | { 37 | if (dimensionX <= 0 || dimensionY <= 0) 38 | { 39 | return null; 40 | } 41 | BitMatrix bits = new BitMatrix(dimensionX, dimensionY); 42 | float[] points = new float[dimensionX << 1]; 43 | for (int y = 0; y < dimensionY; y++) 44 | { 45 | int max = points.Length; 46 | //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" 47 | float iValue = (float)y + 0.5f; 48 | for (int x = 0; x < max; x += 2) 49 | { 50 | //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" 51 | points[x] = (float)(x >> 1) + 0.5f; 52 | points[x + 1] = iValue; 53 | } 54 | transform.transformPoints(points); 55 | // Quick check to see if points transformed to something inside the image; 56 | // sufficient to check the endpoints 57 | if (!checkAndNudgePoints(image, points)) 58 | return null; 59 | try 60 | { 61 | for (int x = 0; x < max; x += 2) 62 | { 63 | //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" 64 | bits[x >> 1, y] = image[(int)points[x], (int)points[x + 1]]; 65 | } 66 | } 67 | catch (System.IndexOutOfRangeException) 68 | { 69 | // This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting 70 | // transform gets "twisted" such that it maps a straight line of points to a set of points 71 | // whose endpoints are in bounds, but others are not. There is probably some mathematical 72 | // way to detect this about the transformation that I don't know yet. 73 | // This results in an ugly runtime exception despite our clever checks above -- can't have 74 | // that. We could check each point's coordinates but that feels duplicative. We settle for 75 | // catching and wrapping ArrayIndexOutOfBoundsException. 76 | return null; 77 | } 78 | } 79 | return bits; 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/common/DetectorResult.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | namespace ZXing.Common 18 | { 19 | ///

Encapsulates the result of detecting a barcode in an image. This includes the raw 20 | /// matrix of black/white pixels corresponding to the barcode, and possibly points of interest 21 | /// in the image, like the location of finder patterns or corners of the barcode in the image.

22 | /// 23 | ///
24 | /// Sean Owen 25 | /// 26 | /// www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source 27 | /// 28 | public class DetectorResult 29 | { 30 | public BitMatrix Bits { get; private set; } 31 | public ResultPoint[] Points { get; private set; } 32 | 33 | public DetectorResult(BitMatrix bits, ResultPoint[] points) 34 | { 35 | Bits = bits; 36 | Points = points; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/common/detector/MathUtils.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | using System; 18 | 19 | namespace ZXing.Common.Detector 20 | { 21 | public static class MathUtils 22 | { 23 | /// 24 | /// Ends up being a bit faster than {@link Math#round(float)}. This merely rounds its 25 | /// argument to the nearest int, where x.5 rounds up to x+1. 26 | /// 27 | /// The d. 28 | /// 29 | public static int round(float d) 30 | { 31 | return (int)(d + 0.5f); 32 | } 33 | 34 | public static float distance(float aX, float aY, float bX, float bY) 35 | { 36 | float xDiff = aX - bX; 37 | float yDiff = aY - bY; 38 | return (float)Math.Sqrt(xDiff * xDiff + yDiff * yDiff); 39 | } 40 | 41 | public static float distance(int aX, int aY, int bX, int bY) 42 | { 43 | int xDiff = aX - bX; 44 | int yDiff = aY - bY; 45 | return (float)Math.Sqrt(xDiff * xDiff + yDiff * yDiff); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/common/reedsolomon/ReedSolomonEncoder.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | 20 | namespace ZXing.Common.ReedSolomon 21 | { 22 | /// 23 | /// Implements Reed-Solomon encoding, as the name implies. 24 | /// 25 | /// Sean Owen 26 | /// William Rucklidge 27 | public sealed class ReedSolomonEncoder 28 | { 29 | private readonly GenericGF field; 30 | private readonly IList cachedGenerators; 31 | 32 | public ReedSolomonEncoder(GenericGF field) 33 | { 34 | this.field = field; 35 | this.cachedGenerators = new List(); 36 | cachedGenerators.Add(new GenericGFPoly(field, new int[] { 1 })); 37 | } 38 | 39 | private GenericGFPoly buildGenerator(int degree) 40 | { 41 | if (degree >= cachedGenerators.Count) 42 | { 43 | var lastGenerator = cachedGenerators[cachedGenerators.Count - 1]; 44 | for (int d = cachedGenerators.Count; d <= degree; d++) 45 | { 46 | var nextGenerator = lastGenerator.multiply(new GenericGFPoly(field, new int[] { 1, field.exp(d - 1 + field.GeneratorBase) })); 47 | cachedGenerators.Add(nextGenerator); 48 | lastGenerator = nextGenerator; 49 | } 50 | } 51 | return cachedGenerators[degree]; 52 | } 53 | 54 | public void encode(int[] toEncode, int ecBytes) 55 | { 56 | if (ecBytes == 0) 57 | { 58 | throw new ArgumentException("No error correction bytes"); 59 | } 60 | var dataBytes = toEncode.Length - ecBytes; 61 | if (dataBytes <= 0) 62 | { 63 | throw new ArgumentException("No data bytes provided"); 64 | } 65 | 66 | var generator = buildGenerator(ecBytes); 67 | var infoCoefficients = new int[dataBytes]; 68 | Array.Copy(toEncode, 0, infoCoefficients, 0, dataBytes); 69 | 70 | var info = new GenericGFPoly(field, infoCoefficients); 71 | info = info.multiplyByMonomial(ecBytes, 1); 72 | 73 | var remainder = info.divide(generator)[1]; 74 | var coefficients = remainder.Coefficients; 75 | var numZeroCoefficients = ecBytes - coefficients.Length; 76 | for (var i = 0; i < numZeroCoefficients; i++) 77 | { 78 | toEncode[dataBytes + i] = 0; 79 | } 80 | 81 | Array.Copy(coefficients, 0, toEncode, dataBytes + numZeroCoefficients, coefficients.Length); 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/qrcode/decoder/DataBlock.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | namespace ZXing.QrCode.Internal 18 | { 19 | ///

Encapsulates a block of data within a QR Code. QR Codes may split their data into 20 | /// multiple blocks, each of which is a unit of data and error-correction codewords. Each 21 | /// is represented by an instance of this class.

22 | /// 23 | ///
24 | /// Sean Owen 25 | /// 26 | /// www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source 27 | /// 28 | internal sealed class DataBlock 29 | { 30 | private readonly int numDataCodewords; 31 | private readonly byte[] codewords; 32 | 33 | private DataBlock(int numDataCodewords, byte[] codewords) 34 | { 35 | this.numDataCodewords = numDataCodewords; 36 | this.codewords = codewords; 37 | } 38 | 39 | ///

When QR Codes use multiple data blocks, they are actually interleaved. 40 | /// That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This 41 | /// method will separate the data into original blocks.

42 | /// 43 | ///
44 | /// bytes as read directly from the QR Code 45 | /// 46 | /// version of the QR Code 47 | /// 48 | /// error-correction level of the QR Code 49 | /// 50 | /// {@link DataBlock}s containing original bytes, "de-interleaved" from representation in the 51 | /// QR Code 52 | /// 53 | internal static DataBlock[] getDataBlocks(byte[] rawCodewords, Version version, ErrorCorrectionLevel ecLevel) 54 | { 55 | 56 | if (rawCodewords.Length != version.TotalCodewords) 57 | { 58 | throw new System.ArgumentException(); 59 | } 60 | 61 | // Figure out the number and size of data blocks used by this version and 62 | // error correction level 63 | Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel); 64 | 65 | // First count the total number of data blocks 66 | int totalBlocks = 0; 67 | Version.ECB[] ecBlockArray = ecBlocks.getECBlocks(); 68 | foreach (var ecBlock in ecBlockArray) 69 | { 70 | totalBlocks += ecBlock.Count; 71 | } 72 | 73 | // Now establish DataBlocks of the appropriate size and number of data codewords 74 | DataBlock[] result = new DataBlock[totalBlocks]; 75 | int numResultBlocks = 0; 76 | foreach (var ecBlock in ecBlockArray) 77 | { 78 | for (int i = 0; i < ecBlock.Count; i++) 79 | { 80 | int numDataCodewords = ecBlock.DataCodewords; 81 | int numBlockCodewords = ecBlocks.ECCodewordsPerBlock + numDataCodewords; 82 | result[numResultBlocks++] = new DataBlock(numDataCodewords, new byte[numBlockCodewords]); 83 | } 84 | } 85 | 86 | // All blocks have the same amount of data, except that the last n 87 | // (where n may be 0) have 1 more byte. Figure out where these start. 88 | int shorterBlocksTotalCodewords = result[0].codewords.Length; 89 | int longerBlocksStartAt = result.Length - 1; 90 | while (longerBlocksStartAt >= 0) 91 | { 92 | int numCodewords = result[longerBlocksStartAt].codewords.Length; 93 | if (numCodewords == shorterBlocksTotalCodewords) 94 | { 95 | break; 96 | } 97 | longerBlocksStartAt--; 98 | } 99 | longerBlocksStartAt++; 100 | 101 | int shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks.ECCodewordsPerBlock; 102 | // The last elements of result may be 1 element longer; 103 | // first fill out as many elements as all of them have 104 | int rawCodewordsOffset = 0; 105 | for (int i = 0; i < shorterBlocksNumDataCodewords; i++) 106 | { 107 | for (int j = 0; j < numResultBlocks; j++) 108 | { 109 | result[j].codewords[i] = rawCodewords[rawCodewordsOffset++]; 110 | } 111 | } 112 | // Fill out the last data block in the longer ones 113 | for (int j = longerBlocksStartAt; j < numResultBlocks; j++) 114 | { 115 | result[j].codewords[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++]; 116 | } 117 | // Now add in error correction blocks 118 | int max = result[0].codewords.Length; 119 | for (int i = shorterBlocksNumDataCodewords; i < max; i++) 120 | { 121 | for (int j = 0; j < numResultBlocks; j++) 122 | { 123 | int iOffset = j < longerBlocksStartAt ? i : i + 1; 124 | result[j].codewords[iOffset] = rawCodewords[rawCodewordsOffset++]; 125 | } 126 | } 127 | return result; 128 | } 129 | 130 | internal int NumDataCodewords 131 | { 132 | get 133 | { 134 | return numDataCodewords; 135 | } 136 | } 137 | 138 | internal byte[] Codewords 139 | { 140 | get 141 | { 142 | return codewords; 143 | } 144 | } 145 | } 146 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/qrcode/decoder/DataMask.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | using ZXing.Common; 18 | 19 | namespace ZXing.QrCode.Internal 20 | { 21 | ///

Encapsulates data masks for the data bits in a QR code, per ISO 18004:2006 6.8. Implementations 22 | /// of this class can un-mask a raw BitMatrix. For simplicity, they will unmask the entire BitMatrix, 23 | /// including areas used for finder patterns, timing patterns, etc. These areas should be unused 24 | /// after the point they are unmasked anyway.

25 | /// 26 | ///

Note that the diagram in section 6.8.1 is misleading since it indicates that i is column position 27 | /// and j is row position. In fact, as the text says, i is row position and j is column position.

28 | /// 29 | ///
30 | /// Sean Owen 31 | /// 32 | /// www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source 33 | /// 34 | abstract class DataMask 35 | { 36 | /// See ISO 18004:2006 6.8.1 37 | private static readonly DataMask[] DATA_MASKS = new DataMask[] 38 | { 39 | new DataMask000(), 40 | new DataMask001(), 41 | new DataMask010(), 42 | new DataMask011(), 43 | new DataMask100(), 44 | new DataMask101(), 45 | new DataMask110(), 46 | new DataMask111() 47 | }; 48 | 49 | private DataMask() 50 | { 51 | } 52 | 53 | ///

Implementations of this method reverse the data masking process applied to a QR Code and 54 | /// make its bits ready to read.

55 | /// 56 | ///
57 | /// representation of QR Code bits 58 | /// 59 | /// dimension of QR Code, represented by bits, being unmasked 60 | /// 61 | internal void unmaskBitMatrix(BitMatrix bits, int dimension) 62 | { 63 | for (int i = 0; i < dimension; i++) 64 | { 65 | for (int j = 0; j < dimension; j++) 66 | { 67 | if (isMasked(i, j)) 68 | { 69 | bits.flip(j, i); 70 | } 71 | } 72 | } 73 | } 74 | 75 | internal abstract bool isMasked(int i, int j); 76 | 77 | /// a value between 0 and 7 indicating one of the eight possible 78 | /// data mask patterns a QR Code may use 79 | /// 80 | /// {@link DataMask} encapsulating the data mask pattern 81 | /// 82 | internal static DataMask forReference(int reference) 83 | { 84 | if (reference < 0 || reference > 7) 85 | { 86 | throw new System.ArgumentException(); 87 | } 88 | return DATA_MASKS[reference]; 89 | } 90 | 91 | /// 000: mask bits for which (x + y) mod 2 == 0 92 | private sealed class DataMask000 : DataMask 93 | { 94 | internal override bool isMasked(int i, int j) 95 | { 96 | return ((i + j) & 0x01) == 0; 97 | } 98 | } 99 | 100 | /// 001: mask bits for which x mod 2 == 0 101 | private sealed class DataMask001 : DataMask 102 | { 103 | internal override bool isMasked(int i, int j) 104 | { 105 | return (i & 0x01) == 0; 106 | } 107 | } 108 | 109 | /// 010: mask bits for which y mod 3 == 0 110 | private sealed class DataMask010 : DataMask 111 | { 112 | internal override bool isMasked(int i, int j) 113 | { 114 | return j % 3 == 0; 115 | } 116 | } 117 | 118 | /// 011: mask bits for which (x + y) mod 3 == 0 119 | private sealed class DataMask011 : DataMask 120 | { 121 | internal override bool isMasked(int i, int j) 122 | { 123 | return (i + j) % 3 == 0; 124 | } 125 | } 126 | 127 | /// 100: mask bits for which (x/2 + y/3) mod 2 == 0 128 | private sealed class DataMask100 : DataMask 129 | { 130 | internal override bool isMasked(int i, int j) 131 | { 132 | return ((((int)((uint)i >> 1)) + (j / 3)) & 0x01) == 0; 133 | } 134 | } 135 | 136 | /// 101: mask bits for which xy mod 2 + xy mod 3 == 0 137 | private sealed class DataMask101 : DataMask 138 | { 139 | internal override bool isMasked(int i, int j) 140 | { 141 | int temp = i * j; 142 | return (temp & 0x01) + (temp % 3) == 0; 143 | } 144 | } 145 | 146 | /// 110: mask bits for which (xy mod 2 + xy mod 3) mod 2 == 0 147 | private sealed class DataMask110 : DataMask 148 | { 149 | internal override bool isMasked(int i, int j) 150 | { 151 | int temp = i * j; 152 | return (((temp & 0x01) + (temp % 3)) & 0x01) == 0; 153 | } 154 | } 155 | 156 | /// 111: mask bits for which ((x+y)mod 2 + xy mod 3) mod 2 == 0 157 | private sealed class DataMask111 : DataMask 158 | { 159 | internal override bool isMasked(int i, int j) 160 | { 161 | return ((((i + j) & 0x01) + ((i * j) % 3)) & 0x01) == 0; 162 | } 163 | } 164 | } 165 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/qrcode/decoder/ErrorCorrectionLevel.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | using System; 18 | 19 | namespace ZXing.QrCode.Internal 20 | { 21 | /// 22 | ///

See ISO 18004:2006, 6.5.1. This enum encapsulates the four error correction levels 23 | /// defined by the QR code standard.

24 | ///
25 | /// Sean Owen 26 | public sealed class ErrorCorrectionLevel 27 | { 28 | /// L = ~7% correction 29 | public static readonly ErrorCorrectionLevel L = new ErrorCorrectionLevel(0, 0x01, "L"); 30 | /// M = ~15% correction 31 | public static readonly ErrorCorrectionLevel M = new ErrorCorrectionLevel(1, 0x00, "M"); 32 | /// Q = ~25% correction 33 | public static readonly ErrorCorrectionLevel Q = new ErrorCorrectionLevel(2, 0x03, "Q"); 34 | /// H = ~30% correction 35 | public static readonly ErrorCorrectionLevel H = new ErrorCorrectionLevel(3, 0x02, "H"); 36 | 37 | private static readonly ErrorCorrectionLevel[] FOR_BITS = new [] { M, L, H, Q }; 38 | 39 | private readonly int bits; 40 | 41 | private ErrorCorrectionLevel(int ordinal, int bits, String name) 42 | { 43 | this.ordinal_Renamed_Field = ordinal; 44 | this.bits = bits; 45 | this.name = name; 46 | } 47 | 48 | /// 49 | /// Gets the bits. 50 | /// 51 | public int Bits 52 | { 53 | get 54 | { 55 | return bits; 56 | } 57 | } 58 | 59 | /// 60 | /// Gets the name. 61 | /// 62 | public String Name 63 | { 64 | get 65 | { 66 | return name; 67 | } 68 | } 69 | 70 | private readonly int ordinal_Renamed_Field; 71 | private readonly String name; 72 | 73 | /// 74 | /// Ordinals this instance. 75 | /// 76 | /// 77 | public int ordinal() 78 | { 79 | return ordinal_Renamed_Field; 80 | } 81 | 82 | /// 83 | /// Returns a that represents this instance. 84 | /// 85 | /// 86 | /// A that represents this instance. 87 | /// 88 | public override String ToString() 89 | { 90 | return name; 91 | } 92 | 93 | /// 94 | /// Fors the bits. 95 | /// 96 | /// int containing the two bits encoding a QR Code's error correction level 97 | /// 98 | /// representing the encoded error correction level 99 | /// 100 | public static ErrorCorrectionLevel forBits(int bits) 101 | { 102 | if (bits < 0 || bits >= FOR_BITS.Length) 103 | { 104 | throw new ArgumentException(); 105 | } 106 | return FOR_BITS[bits]; 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/qrcode/decoder/Mode.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | using System; 18 | 19 | namespace ZXing.QrCode.Internal 20 | { 21 | /// 22 | ///

See ISO 18004:2006, 6.4.1, Tables 2 and 3. This enum encapsulates the various modes in which 23 | /// data can be encoded to bits in the QR code standard.

24 | ///
25 | /// Sean Owen 26 | public sealed class Mode 27 | { 28 | /// 29 | /// Gets the name. 30 | /// 31 | public String Name 32 | { 33 | get 34 | { 35 | return name; 36 | } 37 | } 38 | 39 | // No, we can't use an enum here. J2ME doesn't support it. 40 | 41 | /// 42 | /// 43 | /// 44 | public static readonly Mode TERMINATOR = new Mode(new int[] { 0, 0, 0 }, 0x00, "TERMINATOR"); // Not really a mode... 45 | /// 46 | /// 47 | /// 48 | public static readonly Mode NUMERIC = new Mode(new int[] { 10, 12, 14 }, 0x01, "NUMERIC"); 49 | /// 50 | /// 51 | /// 52 | public static readonly Mode ALPHANUMERIC = new Mode(new int[] { 9, 11, 13 }, 0x02, "ALPHANUMERIC"); 53 | /// 54 | /// 55 | /// 56 | public static readonly Mode STRUCTURED_APPEND = new Mode(new int[] { 0, 0, 0 }, 0x03, "STRUCTURED_APPEND"); // Not supported 57 | /// 58 | /// 59 | /// 60 | public static readonly Mode BYTE = new Mode(new int[] { 8, 16, 16 }, 0x04, "BYTE"); 61 | /// 62 | /// 63 | /// 64 | public static readonly Mode ECI = new Mode(null, 0x07, "ECI"); // character counts don't apply 65 | /// 66 | /// 67 | /// 68 | public static readonly Mode KANJI = new Mode(new int[] { 8, 10, 12 }, 0x08, "KANJI"); 69 | /// 70 | /// 71 | /// 72 | public static readonly Mode FNC1_FIRST_POSITION = new Mode(null, 0x05, "FNC1_FIRST_POSITION"); 73 | /// 74 | /// 75 | /// 76 | public static readonly Mode FNC1_SECOND_POSITION = new Mode(null, 0x09, "FNC1_SECOND_POSITION"); 77 | /// See GBT 18284-2000; "Hanzi" is a transliteration of this mode name. 78 | public static readonly Mode HANZI = new Mode(new int[] { 8, 10, 12 }, 0x0D, "HANZI"); 79 | 80 | private readonly int[] characterCountBitsForVersions; 81 | private readonly int bits; 82 | private readonly String name; 83 | 84 | private Mode(int[] characterCountBitsForVersions, int bits, System.String name) 85 | { 86 | this.characterCountBitsForVersions = characterCountBitsForVersions; 87 | this.bits = bits; 88 | this.name = name; 89 | } 90 | 91 | /// 92 | /// Fors the bits. 93 | /// 94 | /// four bits encoding a QR Code data mode 95 | /// 96 | /// encoded by these bits 97 | /// 98 | /// if bits do not correspond to a known mode 99 | public static Mode forBits(int bits) 100 | { 101 | switch (bits) 102 | { 103 | case 0x0: 104 | return TERMINATOR; 105 | case 0x1: 106 | return NUMERIC; 107 | case 0x2: 108 | return ALPHANUMERIC; 109 | case 0x3: 110 | return STRUCTURED_APPEND; 111 | case 0x4: 112 | return BYTE; 113 | case 0x5: 114 | return FNC1_FIRST_POSITION; 115 | case 0x7: 116 | return ECI; 117 | case 0x8: 118 | return KANJI; 119 | case 0x9: 120 | return FNC1_SECOND_POSITION; 121 | case 0xD: 122 | // 0xD is defined in GBT 18284-2000, may not be supported in foreign country 123 | return HANZI; 124 | default: 125 | throw new ArgumentException(); 126 | } 127 | } 128 | 129 | /// version in question 130 | /// 131 | /// number of bits used, in this QR Code symbol {@link Version}, to encode the 132 | /// count of characters that will follow encoded in this {@link Mode} 133 | /// 134 | public int getCharacterCountBits(Version version) 135 | { 136 | if (characterCountBitsForVersions == null) 137 | { 138 | throw new ArgumentException("Character count doesn't apply to this mode"); 139 | } 140 | int number = version.VersionNumber; 141 | int offset; 142 | if (number <= 9) 143 | { 144 | offset = 0; 145 | } 146 | else if (number <= 26) 147 | { 148 | offset = 1; 149 | } 150 | else 151 | { 152 | offset = 2; 153 | } 154 | return characterCountBitsForVersions[offset]; 155 | } 156 | 157 | /// 158 | /// Gets the bits. 159 | /// 160 | public int Bits 161 | { 162 | get 163 | { 164 | return bits; 165 | } 166 | } 167 | 168 | /// 169 | /// Returns a that represents this instance. 170 | /// 171 | /// 172 | /// A that represents this instance. 173 | /// 174 | public override String ToString() 175 | { 176 | return name; 177 | } 178 | } 179 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/qrcode/decoder/QRCodeDecoderMetaData.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | namespace ZXing.QrCode.Internal 18 | { 19 | /// 20 | /// Meta-data container for QR Code decoding. Instances of this class may be used to convey information back to the 21 | /// decoding caller. Callers are expected to process this. 22 | /// 23 | public sealed class QRCodeDecoderMetaData 24 | { 25 | private readonly bool mirrored; 26 | 27 | /// 28 | /// Initializes a new instance of the class. 29 | /// 30 | /// if set to true [mirrored]. 31 | public QRCodeDecoderMetaData(bool mirrored) 32 | { 33 | this.mirrored = mirrored; 34 | } 35 | 36 | /// 37 | /// true if the QR Code was mirrored. 38 | /// 39 | public bool IsMirrored 40 | { 41 | get { return mirrored; } 42 | } 43 | 44 | /// 45 | /// Apply the result points' order correction due to mirroring. 46 | /// 47 | /// Array of points to apply mirror correction to. 48 | public void applyMirroredCorrection(ResultPoint[] points) 49 | { 50 | if (!mirrored || points == null || points.Length < 3) 51 | { 52 | return; 53 | } 54 | ResultPoint bottomLeft = points[0]; 55 | points[0] = points[2]; 56 | points[2] = bottomLeft; 57 | // No need to 'fix' top-left and alignment pattern. 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/qrcode/detector/AlignmentPattern.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | using System; 18 | 19 | namespace ZXing.QrCode.Internal 20 | { 21 | ///

Encapsulates an alignment pattern, which are the smaller square patterns found in 22 | /// all but the simplest QR Codes.

23 | /// 24 | ///
25 | /// Sean Owen 26 | /// 27 | /// www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source 28 | /// 29 | public sealed class AlignmentPattern : ResultPoint 30 | { 31 | private float estimatedModuleSize; 32 | 33 | internal AlignmentPattern(float posX, float posY, float estimatedModuleSize) 34 | : base(posX, posY) 35 | { 36 | this.estimatedModuleSize = estimatedModuleSize; 37 | } 38 | 39 | ///

Determines if this alignment pattern "about equals" an alignment pattern at the stated 40 | /// position and size -- meaning, it is at nearly the same center with nearly the same size.

41 | ///
42 | internal bool aboutEquals(float moduleSize, float i, float j) 43 | { 44 | if (Math.Abs(i - Y) <= moduleSize && Math.Abs(j - X) <= moduleSize) 45 | { 46 | float moduleSizeDiff = Math.Abs(moduleSize - estimatedModuleSize); 47 | return moduleSizeDiff <= 1.0f || moduleSizeDiff <= estimatedModuleSize; 48 | } 49 | return false; 50 | } 51 | 52 | /// 53 | /// Combines this object's current estimate of a finder pattern position and module size 54 | /// with a new estimate. It returns a new {@code FinderPattern} containing an average of the two. 55 | /// 56 | /// The i. 57 | /// The j. 58 | /// New size of the module. 59 | /// 60 | internal AlignmentPattern combineEstimate(float i, float j, float newModuleSize) 61 | { 62 | float combinedX = (X + j) / 2.0f; 63 | float combinedY = (Y + i) / 2.0f; 64 | float combinedModuleSize = (estimatedModuleSize + newModuleSize) / 2.0f; 65 | return new AlignmentPattern(combinedX, combinedY, combinedModuleSize); 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/qrcode/detector/FinderPattern.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | using System; 18 | 19 | namespace ZXing.QrCode.Internal 20 | { 21 | /// 22 | ///

Encapsulates a finder pattern, which are the three square patterns found in 23 | /// the corners of QR Codes. It also encapsulates a count of similar finder patterns, 24 | /// as a convenience to the finder's bookkeeping.

25 | ///
26 | /// Sean Owen 27 | public sealed class FinderPattern : ResultPoint 28 | { 29 | private readonly float estimatedModuleSize; 30 | private int count; 31 | 32 | internal FinderPattern(float posX, float posY, float estimatedModuleSize) 33 | : this(posX, posY, estimatedModuleSize, 1) 34 | { 35 | this.estimatedModuleSize = estimatedModuleSize; 36 | this.count = 1; 37 | } 38 | 39 | internal FinderPattern(float posX, float posY, float estimatedModuleSize, int count) 40 | : base(posX, posY) 41 | { 42 | this.estimatedModuleSize = estimatedModuleSize; 43 | this.count = count; 44 | } 45 | 46 | /// 47 | /// Gets the size of the estimated module. 48 | /// 49 | /// 50 | /// The size of the estimated module. 51 | /// 52 | public float EstimatedModuleSize 53 | { 54 | get 55 | { 56 | return estimatedModuleSize; 57 | } 58 | } 59 | 60 | internal int Count 61 | { 62 | get 63 | { 64 | return count; 65 | } 66 | } 67 | 68 | /* 69 | internal void incrementCount() 70 | { 71 | this.count++; 72 | } 73 | */ 74 | 75 | ///

Determines if this finder pattern "about equals" a finder pattern at the stated 76 | /// position and size -- meaning, it is at nearly the same center with nearly the same size.

77 | ///
78 | internal bool aboutEquals(float moduleSize, float i, float j) 79 | { 80 | if (Math.Abs(i - Y) <= moduleSize && Math.Abs(j - X) <= moduleSize) 81 | { 82 | float moduleSizeDiff = Math.Abs(moduleSize - estimatedModuleSize); 83 | return moduleSizeDiff <= 1.0f || moduleSizeDiff <= estimatedModuleSize; 84 | 85 | } 86 | return false; 87 | } 88 | 89 | /// 90 | /// Combines this object's current estimate of a finder pattern position and module size 91 | /// with a new estimate. It returns a new {@code FinderPattern} containing a weighted average 92 | /// based on count. 93 | /// 94 | /// The i. 95 | /// The j. 96 | /// New size of the module. 97 | /// 98 | internal FinderPattern combineEstimate(float i, float j, float newModuleSize) 99 | { 100 | int combinedCount = count + 1; 101 | float combinedX = (count * X + j) / combinedCount; 102 | float combinedY = (count * Y + i) / combinedCount; 103 | float combinedModuleSize = (count * estimatedModuleSize + newModuleSize) / combinedCount; 104 | return new FinderPattern(combinedX, combinedY, combinedModuleSize, combinedCount); 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/qrcode/detector/FinderPatternInfo.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | namespace ZXing.QrCode.Internal 18 | { 19 | /// 20 | ///

Encapsulates information about finder patterns in an image, including the location of 21 | /// the three finder patterns, and their estimated module size.

22 | ///
23 | /// Sean Owen 24 | public sealed class FinderPatternInfo 25 | { 26 | private readonly FinderPattern bottomLeft; 27 | private readonly FinderPattern topLeft; 28 | private readonly FinderPattern topRight; 29 | 30 | /// 31 | /// Initializes a new instance of the class. 32 | /// 33 | /// The pattern centers. 34 | public FinderPatternInfo(FinderPattern[] patternCenters) 35 | { 36 | this.bottomLeft = patternCenters[0]; 37 | this.topLeft = patternCenters[1]; 38 | this.topRight = patternCenters[2]; 39 | } 40 | 41 | /// 42 | /// Gets the bottom left. 43 | /// 44 | public FinderPattern BottomLeft 45 | { 46 | get 47 | { 48 | return bottomLeft; 49 | } 50 | } 51 | 52 | /// 53 | /// Gets the top left. 54 | /// 55 | public FinderPattern TopLeft 56 | { 57 | get 58 | { 59 | return topLeft; 60 | } 61 | } 62 | 63 | /// 64 | /// Gets the top right. 65 | /// 66 | public FinderPattern TopRight 67 | { 68 | get 69 | { 70 | return topRight; 71 | } 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/qrcode/encoder/BlockPair.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | namespace ZXing.QrCode.Internal 18 | { 19 | internal sealed class BlockPair 20 | { 21 | private readonly byte[] dataBytes; 22 | private readonly byte[] errorCorrectionBytes; 23 | 24 | public BlockPair(byte[] data, byte[] errorCorrection) 25 | { 26 | dataBytes = data; 27 | errorCorrectionBytes = errorCorrection; 28 | } 29 | 30 | public byte[] DataBytes 31 | { 32 | get { return dataBytes; } 33 | } 34 | 35 | public byte[] ErrorCorrectionBytes 36 | { 37 | get { return errorCorrectionBytes; } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/qrcode/encoder/ByteMatrix.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | using System; 18 | using System.Text; 19 | 20 | namespace ZXing.QrCode.Internal 21 | { 22 | /// 23 | /// JAVAPORT: The original code was a 2D array of ints, but since it only ever gets assigned 24 | /// 0, 1 and 2 I'm going to use less memory and go with bytes. 25 | /// 26 | /// dswitkin@google.com (Daniel Switkin) 27 | public sealed class ByteMatrix 28 | { 29 | private readonly byte[][] bytes; 30 | private readonly int width; 31 | private readonly int height; 32 | 33 | /// 34 | /// Initializes a new instance of the class. 35 | /// 36 | /// The width. 37 | /// The height. 38 | public ByteMatrix(int width, int height) 39 | { 40 | bytes = new byte[height][]; 41 | for (var i = 0; i < height; i++) 42 | bytes[i] = new byte[width]; 43 | this.width = width; 44 | this.height = height; 45 | } 46 | 47 | /// 48 | /// Gets the height. 49 | /// 50 | public int Height 51 | { 52 | get { return height; } 53 | } 54 | 55 | /// 56 | /// Gets the width. 57 | /// 58 | public int Width 59 | { 60 | get { return width; } 61 | } 62 | 63 | /// 64 | /// Gets or sets the with the specified x. 65 | /// 66 | public int this[int x, int y] 67 | { 68 | get { return bytes[y][x]; } 69 | set { bytes[y][x] = (byte)value; } 70 | } 71 | 72 | /// 73 | /// an internal representation as bytes, in row-major order. array[y][x] represents point (x,y) 74 | /// 75 | public byte[][] Array 76 | { 77 | get { return bytes; } 78 | } 79 | 80 | /// 81 | /// Sets the specified x. 82 | /// 83 | /// The x. 84 | /// The y. 85 | /// The value. 86 | public void set(int x, int y, byte value) 87 | { 88 | bytes[y][x] = value; 89 | } 90 | 91 | /// 92 | /// Sets the specified x. 93 | /// 94 | /// The x. 95 | /// The y. 96 | /// if set to true [value]. 97 | public void set(int x, int y, bool value) 98 | { 99 | bytes[y][x] = (byte)(value ? 1 : 0); 100 | } 101 | 102 | /// 103 | /// Clears the specified value. 104 | /// 105 | /// The value. 106 | public void clear(byte value) 107 | { 108 | for (int y = 0; y < height; ++y) 109 | { 110 | for (int x = 0; x < width; ++x) 111 | { 112 | bytes[y][x] = value; 113 | } 114 | } 115 | } 116 | 117 | /// 118 | /// Returns a that represents this instance. 119 | /// 120 | /// 121 | /// A that represents this instance. 122 | /// 123 | override public String ToString() 124 | { 125 | var result = new StringBuilder(2 * width * height + 2); 126 | for (int y = 0; y < height; ++y) 127 | { 128 | for (int x = 0; x < width; ++x) 129 | { 130 | switch (bytes[y][x]) 131 | { 132 | case 0: 133 | result.Append(" 0"); 134 | break; 135 | case 1: 136 | result.Append(" 1"); 137 | break; 138 | default: 139 | result.Append(" "); 140 | break; 141 | } 142 | } 143 | result.Append('\n'); 144 | } 145 | return result.ToString(); 146 | } 147 | } 148 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/3rd/zxing/qrcode/encoder/QRCode.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 ZXing authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | using System; 18 | using System.Text; 19 | 20 | namespace ZXing.QrCode.Internal 21 | { 22 | /// satorux@google.com (Satoru Takabayashi) - creator 23 | /// dswitkin@google.com (Daniel Switkin) - ported from C++ 24 | public sealed class QRCode 25 | { 26 | /// 27 | /// 28 | /// 29 | public static int NUM_MASK_PATTERNS = 8; 30 | 31 | /// 32 | /// Initializes a new instance of the class. 33 | /// 34 | public QRCode() 35 | { 36 | MaskPattern = -1; 37 | } 38 | 39 | /// 40 | /// Gets or sets the mode. 41 | /// 42 | /// 43 | /// The mode. 44 | /// 45 | public Mode Mode { get; set; } 46 | 47 | /// 48 | /// Gets or sets the EC level. 49 | /// 50 | /// 51 | /// The EC level. 52 | /// 53 | public ErrorCorrectionLevel ECLevel { get; set; } 54 | 55 | /// 56 | /// Gets or sets the version. 57 | /// 58 | /// 59 | /// The version. 60 | /// 61 | public Version Version { get; set; } 62 | 63 | /// 64 | /// Gets or sets the mask pattern. 65 | /// 66 | /// 67 | /// The mask pattern. 68 | /// 69 | public int MaskPattern { get; set; } 70 | 71 | /// 72 | /// Gets or sets the matrix. 73 | /// 74 | /// 75 | /// The matrix. 76 | /// 77 | public ByteMatrix Matrix { get; set; } 78 | 79 | /// 80 | /// Returns a that represents this instance. 81 | /// 82 | /// 83 | /// A that represents this instance. 84 | /// 85 | public override String ToString() 86 | { 87 | var result = new StringBuilder(200); 88 | result.Append("<<\n"); 89 | result.Append(" mode: "); 90 | result.Append(Mode); 91 | result.Append("\n ecLevel: "); 92 | result.Append(ECLevel); 93 | result.Append("\n version: "); 94 | if (Version == null) 95 | result.Append("null"); 96 | else 97 | result.Append(Version); 98 | result.Append("\n maskPattern: "); 99 | result.Append(MaskPattern); 100 | if (Matrix == null) 101 | { 102 | result.Append("\n matrix: null\n"); 103 | } 104 | else 105 | { 106 | result.Append("\n matrix:\n"); 107 | result.Append(Matrix.ToString()); 108 | } 109 | result.Append(">>\n"); 110 | return result.ToString(); 111 | } 112 | 113 | /// 114 | /// Check if "mask_pattern" is valid. 115 | /// 116 | /// The mask pattern. 117 | /// 118 | /// true if [is valid mask pattern] [the specified mask pattern]; otherwise, false. 119 | /// 120 | public static bool isValidMaskPattern(int maskPattern) 121 | { 122 | return maskPattern >= 0 && maskPattern < NUM_MASK_PATTERNS; 123 | } 124 | } 125 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/Controller/FileManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.IO.Compression; 5 | using System.Text; 6 | 7 | namespace Shadowsocks.Controller 8 | { 9 | public class FileManager 10 | { 11 | public static bool ByteArrayToFile(string fileName, byte[] content) 12 | { 13 | try 14 | { 15 | System.IO.FileStream _FileStream = 16 | new System.IO.FileStream(fileName, System.IO.FileMode.Create, 17 | System.IO.FileAccess.Write); 18 | _FileStream.Write(content, 0, content.Length); 19 | _FileStream.Close(); 20 | return true; 21 | } 22 | catch (Exception _Exception) 23 | { 24 | Console.WriteLine("Exception caught in process: {0}", 25 | _Exception.ToString()); 26 | } 27 | return false; 28 | } 29 | 30 | public static void UncompressFile(string fileName, byte[] content) 31 | { 32 | FileStream destinationFile = File.Create(fileName); 33 | 34 | // Because the uncompressed size of the file is unknown, 35 | // we are using an arbitrary buffer size. 36 | byte[] buffer = new byte[4096]; 37 | int n; 38 | 39 | using (GZipStream input = new GZipStream(new MemoryStream(content), 40 | CompressionMode.Decompress, false)) 41 | { 42 | while (true) 43 | { 44 | n = input.Read(buffer, 0, buffer.Length); 45 | if (n == 0) 46 | { 47 | break; 48 | } 49 | destinationFile.Write(buffer, 0, n); 50 | } 51 | } 52 | destinationFile.Close(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Controller/I18N.cs: -------------------------------------------------------------------------------- 1 | using Shadowsocks.Properties; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | 7 | namespace Shadowsocks.Controller 8 | { 9 | public class I18N 10 | { 11 | protected static Dictionary Strings; 12 | static I18N() 13 | { 14 | Strings = new Dictionary(); 15 | 16 | if (System.Globalization.CultureInfo.CurrentCulture.IetfLanguageTag.ToLowerInvariant().StartsWith("zh")) 17 | { 18 | string[] lines = Regex.Split(Resources.cn, "\r\n|\r|\n"); 19 | foreach (string line in lines) 20 | { 21 | if (line.StartsWith("#")) 22 | { 23 | continue; 24 | } 25 | string[] kv = Regex.Split(line, "="); 26 | if (kv.Length == 2) 27 | { 28 | Strings[kv[0]] = kv[1]; 29 | } 30 | } 31 | } 32 | } 33 | 34 | public static string GetString(string key) 35 | { 36 | if (Strings.ContainsKey(key)) 37 | { 38 | return Strings[key]; 39 | } 40 | else 41 | { 42 | return key; 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Controller/Logging.cs: -------------------------------------------------------------------------------- 1 | using Shadowsocks.Util; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Net.Sockets; 6 | using System.Text; 7 | 8 | namespace Shadowsocks.Controller 9 | { 10 | public class Logging 11 | { 12 | public static string LogFile; 13 | 14 | public static bool OpenLogFile() 15 | { 16 | try 17 | { 18 | string temppath = Utils.GetTempPath(); 19 | LogFile = Path.Combine(temppath, "shadowsocks.log"); 20 | FileStream fs = new FileStream(LogFile, FileMode.Append); 21 | StreamWriterWithTimestamp sw = new StreamWriterWithTimestamp(fs); 22 | sw.AutoFlush = true; 23 | Console.SetOut(sw); 24 | Console.SetError(sw); 25 | 26 | return true; 27 | } 28 | catch (IOException e) 29 | { 30 | Console.WriteLine(e.ToString()); 31 | return false; 32 | } 33 | } 34 | 35 | public static void Debug(object o) 36 | { 37 | 38 | #if DEBUG 39 | Console.WriteLine(o); 40 | #endif 41 | } 42 | 43 | public static void LogUsefulException(Exception e) 44 | { 45 | // just log useful exceptions, not all of them 46 | if (e is SocketException) 47 | { 48 | SocketException se = (SocketException)e; 49 | if (se.SocketErrorCode == SocketError.ConnectionAborted) 50 | { 51 | // closed by browser when sending 52 | // normally happens when download is canceled or a tab is closed before page is loaded 53 | } 54 | else if (se.SocketErrorCode == SocketError.ConnectionReset) 55 | { 56 | // received rst 57 | } 58 | else if (se.SocketErrorCode == SocketError.NotConnected) 59 | { 60 | // close when not connected 61 | } 62 | else 63 | { 64 | Console.WriteLine(e); 65 | } 66 | } 67 | else if (e is ObjectDisposedException) 68 | { 69 | } 70 | else 71 | { 72 | Console.WriteLine(e); 73 | } 74 | } 75 | } 76 | 77 | // Simply extended System.IO.StreamWriter for adding timestamp workaround 78 | public class StreamWriterWithTimestamp : StreamWriter 79 | { 80 | public StreamWriterWithTimestamp(Stream stream) : base(stream) 81 | { 82 | } 83 | 84 | private string GetTimestamp() 85 | { 86 | return "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "] "; 87 | } 88 | 89 | public override void WriteLine(string value) 90 | { 91 | base.WriteLine(GetTimestamp() + value); 92 | } 93 | 94 | public override void Write(string value) 95 | { 96 | base.Write(GetTimestamp() + value); 97 | } 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Net.NetworkInformation; 6 | using System.Threading; 7 | using Shadowsocks.Model; 8 | using System.Reflection; 9 | using Shadowsocks.Util; 10 | 11 | namespace Shadowsocks.Controller 12 | { 13 | class AvailabilityStatistics 14 | { 15 | private static readonly string StatisticsFilesName = "shadowsocks.availability.csv"; 16 | private static readonly string Delimiter = ","; 17 | private static readonly int Timeout = 500; 18 | private static readonly int Repeat = 4; //repeat times every evaluation 19 | private static readonly int Interval = 10 * 60 * 1000; //evaluate proxies every 15 minutes 20 | private Timer timer = null; 21 | private State state = null; 22 | private List servers; 23 | 24 | public static string AvailabilityStatisticsFile; 25 | 26 | //static constructor to initialize every public static fields before refereced 27 | static AvailabilityStatistics() 28 | { 29 | string temppath = Utils.GetTempPath(); 30 | AvailabilityStatisticsFile = Path.Combine(temppath, StatisticsFilesName); 31 | } 32 | 33 | public bool Set(bool enabled) 34 | { 35 | try 36 | { 37 | if (enabled) 38 | { 39 | if (timer?.Change(0, Interval) == null) 40 | { 41 | state = new State(); 42 | timer = new Timer(Evaluate, state, 0, Interval); 43 | } 44 | } 45 | else 46 | { 47 | timer?.Dispose(); 48 | } 49 | return true; 50 | } 51 | catch (Exception e) 52 | { 53 | Logging.LogUsefulException(e); 54 | return false; 55 | } 56 | } 57 | 58 | private void Evaluate(object obj) 59 | { 60 | Ping ping = new Ping(); 61 | State state = (State) obj; 62 | foreach (var server in servers) 63 | { 64 | Logging.Debug("eveluating " + server.FriendlyName()); 65 | foreach (var _ in Enumerable.Range(0, Repeat)) 66 | { 67 | //TODO: do simple analyze of data to provide friendly message, like package loss. 68 | string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); 69 | //ICMP echo. we can also set options and special bytes 70 | //seems no need to use SendPingAsync 71 | try 72 | { 73 | PingReply reply = ping.Send(server.server, Timeout); 74 | state.data = new List>(); 75 | state.data.Add(new KeyValuePair("Timestamp", timestamp)); 76 | state.data.Add(new KeyValuePair("Server", server.FriendlyName())); 77 | state.data.Add(new KeyValuePair("Status", reply.Status.ToString())); 78 | state.data.Add(new KeyValuePair("RoundtripTime", reply.RoundtripTime.ToString())); 79 | //state.data.Add(new KeyValuePair("data", reply.Buffer.ToString())); // The data of reply 80 | Append(state.data); 81 | } 82 | catch (Exception e) 83 | { 84 | Logging.LogUsefulException(e); 85 | } 86 | } 87 | } 88 | } 89 | 90 | private static void Append(List> data) 91 | { 92 | string dataLine = string.Join(Delimiter, data.Select(kv => kv.Value).ToArray()); 93 | string[] lines; 94 | if (!File.Exists(AvailabilityStatisticsFile)) 95 | { 96 | string headerLine = string.Join(Delimiter, data.Select(kv => kv.Key).ToArray()); 97 | lines = new string[] { headerLine, dataLine }; 98 | } 99 | else 100 | { 101 | lines = new string[] { dataLine }; 102 | } 103 | File.AppendAllLines(AvailabilityStatisticsFile, lines); 104 | } 105 | 106 | internal void UpdateConfiguration(Configuration _config) 107 | { 108 | Set(_config.availabilityStatistics); 109 | servers = _config.configs; 110 | } 111 | 112 | private class State 113 | { 114 | public List> data = new List>(); 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Controller/Service/GfwListUpdater.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Net; 5 | using System.IO; 6 | using Shadowsocks.Properties; 7 | using SimpleJson; 8 | using Shadowsocks.Util; 9 | using Shadowsocks.Model; 10 | 11 | namespace Shadowsocks.Controller 12 | { 13 | public class GFWListUpdater 14 | { 15 | private const string GFWLIST_URL = "https://autoproxy-gfwlist.googlecode.com/svn/trunk/gfwlist.txt"; 16 | 17 | private static string PAC_FILE = PACServer.PAC_FILE; 18 | 19 | private static string USER_RULE_FILE = PACServer.USER_RULE_FILE; 20 | 21 | public event EventHandler UpdateCompleted; 22 | 23 | public event ErrorEventHandler Error; 24 | 25 | public class ResultEventArgs : EventArgs 26 | { 27 | public bool Success; 28 | 29 | public ResultEventArgs(bool success) 30 | { 31 | this.Success = success; 32 | } 33 | } 34 | 35 | private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) 36 | { 37 | try 38 | { 39 | List lines = ParseResult(e.Result); 40 | if (File.Exists(USER_RULE_FILE)) 41 | { 42 | string local = File.ReadAllText(USER_RULE_FILE, Encoding.UTF8); 43 | string[] rules = local.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); 44 | foreach(string rule in rules) 45 | { 46 | if (rule.StartsWith("!") || rule.StartsWith("[")) 47 | continue; 48 | lines.Add(rule); 49 | } 50 | } 51 | string abpContent = Utils.UnGzip(Resources.abp_js); 52 | abpContent = abpContent.Replace("__RULES__", SimpleJson.SimpleJson.SerializeObject(lines)); 53 | if (File.Exists(PAC_FILE)) 54 | { 55 | string original = File.ReadAllText(PAC_FILE, Encoding.UTF8); 56 | if (original == abpContent) 57 | { 58 | UpdateCompleted(this, new ResultEventArgs(false)); 59 | return; 60 | } 61 | } 62 | File.WriteAllText(PAC_FILE, abpContent, Encoding.UTF8); 63 | if (UpdateCompleted != null) 64 | { 65 | UpdateCompleted(this, new ResultEventArgs(true)); 66 | } 67 | } 68 | catch (Exception ex) 69 | { 70 | if (Error != null) 71 | { 72 | Error(this, new ErrorEventArgs(ex)); 73 | } 74 | } 75 | } 76 | 77 | public void UpdatePACFromGFWList(Configuration config) 78 | { 79 | WebClient http = new WebClient(); 80 | http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), config.localPort); 81 | http.DownloadStringCompleted += http_DownloadStringCompleted; 82 | http.DownloadStringAsync(new Uri(GFWLIST_URL)); 83 | } 84 | 85 | public List ParseResult(string response) 86 | { 87 | byte[] bytes = Convert.FromBase64String(response); 88 | string content = Encoding.ASCII.GetString(bytes); 89 | string[] lines = content.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); 90 | List valid_lines = new List(lines.Length); 91 | foreach (string line in lines) 92 | { 93 | if (line.StartsWith("!") || line.StartsWith("[")) 94 | continue; 95 | valid_lines.Add(line); 96 | } 97 | return valid_lines; 98 | } 99 | } 100 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/Controller/Service/UpdateChecker.cs: -------------------------------------------------------------------------------- 1 | using Shadowsocks.Model; 2 | using System; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System.Net; 6 | using System.Reflection; 7 | using System.Text; 8 | using System.Text.RegularExpressions; 9 | using SimpleJson; 10 | 11 | namespace Shadowsocks.Controller 12 | { 13 | public class UpdateChecker 14 | { 15 | private const string UpdateURL = "https://api.github.com/repos/shadowsocks/shadowsocks-windows/releases"; 16 | 17 | public string LatestVersionNumber; 18 | public string LatestVersionURL; 19 | public event EventHandler NewVersionFound; 20 | 21 | public const string Version = "2.5.6"; 22 | 23 | public void CheckUpdate(Configuration config) 24 | { 25 | // TODO test failures 26 | WebClient http = new WebClient(); 27 | http.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.3319.102 Safari/537.36"); 28 | http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), config.localPort); 29 | http.DownloadStringCompleted += http_DownloadStringCompleted; 30 | http.DownloadStringAsync(new Uri(UpdateURL)); 31 | } 32 | 33 | public static int CompareVersion(string l, string r) 34 | { 35 | var ls = l.Split('.'); 36 | var rs = r.Split('.'); 37 | for (int i = 0; i < Math.Max(ls.Length, rs.Length); i++) 38 | { 39 | int lp = (i < ls.Length) ? int.Parse(ls[i]) : 0; 40 | int rp = (i < rs.Length) ? int.Parse(rs[i]) : 0; 41 | if (lp != rp) 42 | { 43 | return lp - rp; 44 | } 45 | } 46 | return 0; 47 | } 48 | 49 | public class VersionComparer : IComparer 50 | { 51 | // Calls CaseInsensitiveComparer.Compare with the parameters reversed. 52 | public int Compare(string x, string y) 53 | { 54 | return CompareVersion(ParseVersionFromURL(x), ParseVersionFromURL(y)); 55 | } 56 | } 57 | 58 | private static string ParseVersionFromURL(string url) 59 | { 60 | Match match = Regex.Match(url, @".*Shadowsocks-win.*?-([\d\.]+)\.\w+", RegexOptions.IgnoreCase); 61 | if (match.Success) 62 | { 63 | if (match.Groups.Count == 2) 64 | { 65 | return match.Groups[1].Value; 66 | } 67 | } 68 | return null; 69 | } 70 | 71 | private void SortVersions(List versions) 72 | { 73 | versions.Sort(new VersionComparer()); 74 | } 75 | 76 | private bool IsNewVersion(string url) 77 | { 78 | if (url.IndexOf("prerelease") >= 0) 79 | { 80 | return false; 81 | } 82 | string version = ParseVersionFromURL(url); 83 | if (version == null) 84 | { 85 | return false; 86 | } 87 | string currentVersion = Version; 88 | 89 | return CompareVersion(version, currentVersion) > 0; 90 | } 91 | 92 | private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) 93 | { 94 | try 95 | { 96 | string response = e.Result; 97 | 98 | JsonArray result = (JsonArray)SimpleJson.SimpleJson.DeserializeObject(e.Result); 99 | 100 | List versions = new List(); 101 | foreach (JsonObject release in result) 102 | { 103 | if ((bool)release["prerelease"]) 104 | { 105 | continue; 106 | } 107 | foreach (JsonObject asset in (JsonArray)release["assets"]) 108 | { 109 | string url = (string)asset["browser_download_url"]; 110 | if (IsNewVersion(url)) 111 | { 112 | versions.Add(url); 113 | } 114 | } 115 | } 116 | 117 | if (versions.Count == 0) 118 | { 119 | return; 120 | } 121 | // sort versions 122 | SortVersions(versions); 123 | LatestVersionURL = versions[versions.Count - 1]; 124 | LatestVersionNumber = ParseVersionFromURL(LatestVersionURL); 125 | if (NewVersionFound != null) 126 | { 127 | NewVersionFound(this, new EventArgs()); 128 | } 129 | } 130 | catch (Exception ex) 131 | { 132 | Logging.Debug(ex.ToString()); 133 | return; 134 | } 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Controller/Strategy/BalancingStrategy.cs: -------------------------------------------------------------------------------- 1 | using Shadowsocks.Controller; 2 | using Shadowsocks.Model; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Net; 6 | using System.Text; 7 | 8 | namespace Shadowsocks.Controller.Strategy 9 | { 10 | class BalancingStrategy : IStrategy 11 | { 12 | ShadowsocksController _controller; 13 | Random _random; 14 | 15 | public BalancingStrategy(ShadowsocksController controller) 16 | { 17 | _controller = controller; 18 | _random = new Random(); 19 | } 20 | 21 | public string Name 22 | { 23 | get { return I18N.GetString("Load Balance"); } 24 | } 25 | 26 | public string ID 27 | { 28 | get { return "com.shadowsocks.strategy.balancing"; } 29 | } 30 | 31 | public void ReloadServers() 32 | { 33 | // do nothing 34 | } 35 | 36 | public Server GetAServer(IStrategyCallerType type, IPEndPoint localIPEndPoint) 37 | { 38 | var configs = _controller.GetCurrentConfiguration().configs; 39 | int index; 40 | if (type == IStrategyCallerType.TCP) 41 | { 42 | index = _random.Next(); 43 | } 44 | else 45 | { 46 | index = localIPEndPoint.GetHashCode(); 47 | } 48 | return configs[index % configs.Count]; 49 | } 50 | 51 | public void UpdateLatency(Model.Server server, TimeSpan latency) 52 | { 53 | // do nothing 54 | } 55 | 56 | public void UpdateLastRead(Model.Server server) 57 | { 58 | // do nothing 59 | } 60 | 61 | public void UpdateLastWrite(Model.Server server) 62 | { 63 | // do nothing 64 | } 65 | 66 | public void SetFailure(Model.Server server) 67 | { 68 | // do nothing 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Controller/Strategy/IStrategy.cs: -------------------------------------------------------------------------------- 1 | using Shadowsocks.Model; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Net; 5 | using System.Text; 6 | 7 | namespace Shadowsocks.Controller.Strategy 8 | { 9 | public enum IStrategyCallerType 10 | { 11 | TCP, 12 | UDP 13 | } 14 | 15 | /* 16 | * IStrategy 17 | * 18 | * Subclasses must be thread-safe 19 | */ 20 | public interface IStrategy 21 | { 22 | string Name { get; } 23 | 24 | string ID { get; } 25 | 26 | /* 27 | * Called when servers need to be reloaded, i.e. new configuration saved 28 | */ 29 | void ReloadServers(); 30 | 31 | /* 32 | * Get a new server to use in TCPRelay or UDPRelay 33 | */ 34 | Server GetAServer(IStrategyCallerType type, IPEndPoint localIPEndPoint); 35 | 36 | /* 37 | * TCPRelay will call this when latency of a server detected 38 | */ 39 | void UpdateLatency(Server server, TimeSpan latency); 40 | 41 | /* 42 | * TCPRelay will call this when reading from a server 43 | */ 44 | void UpdateLastRead(Server server); 45 | 46 | /* 47 | * TCPRelay will call this when writing to a server 48 | */ 49 | void UpdateLastWrite(Server server); 50 | 51 | /* 52 | * TCPRelay will call this when fatal failure detected 53 | */ 54 | void SetFailure(Server server); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Controller/Strategy/StrategyManager.cs: -------------------------------------------------------------------------------- 1 | using Shadowsocks.Controller; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Shadowsocks.Controller.Strategy 7 | { 8 | class StrategyManager 9 | { 10 | List _strategies; 11 | public StrategyManager(ShadowsocksController controller) 12 | { 13 | _strategies = new List(); 14 | _strategies.Add(new BalancingStrategy(controller)); 15 | _strategies.Add(new HighAvailabilityStrategy(controller)); 16 | _strategies.Add(new SimplyChooseByStatisticsStrategy(controller)); 17 | // TODO: load DLL plugins 18 | } 19 | public IList GetStrategies() 20 | { 21 | return _strategies; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Controller/System/AutoStartup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using Microsoft.Win32; 4 | 5 | namespace Shadowsocks.Controller 6 | { 7 | class AutoStartup 8 | { 9 | public static bool Set(bool enabled) 10 | { 11 | try 12 | { 13 | string path = Application.ExecutablePath; 14 | RegistryKey runKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); 15 | if (enabled) 16 | { 17 | runKey.SetValue("Shadowsocks", path); 18 | } 19 | else 20 | { 21 | runKey.DeleteValue("Shadowsocks"); 22 | } 23 | runKey.Close(); 24 | return true; 25 | } 26 | catch (Exception e) 27 | { 28 | Logging.LogUsefulException(e); 29 | return false; 30 | } 31 | } 32 | 33 | public static bool Check() 34 | { 35 | try 36 | { 37 | string path = Application.ExecutablePath; 38 | RegistryKey runKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run"); 39 | string[] runList = runKey.GetValueNames(); 40 | runKey.Close(); 41 | foreach (string item in runList) 42 | { 43 | if (item.Equals("Shadowsocks")) 44 | return true; 45 | } 46 | return false; 47 | } 48 | catch (Exception e) 49 | { 50 | Logging.LogUsefulException(e); 51 | return false; 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Controller/System/SystemProxy.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | using Microsoft.Win32; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | using System.IO; 8 | using Shadowsocks.Model; 9 | 10 | namespace Shadowsocks.Controller 11 | { 12 | public class SystemProxy 13 | { 14 | 15 | [DllImport("wininet.dll")] 16 | public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength); 17 | public const int INTERNET_OPTION_SETTINGS_CHANGED = 39; 18 | public const int INTERNET_OPTION_REFRESH = 37; 19 | static bool _settingsReturn, _refreshReturn; 20 | 21 | public static void NotifyIE() 22 | { 23 | // These lines implement the Interface in the beginning of program 24 | // They cause the OS to refresh the settings, causing IP to realy update 25 | _settingsReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0); 26 | _refreshReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0); 27 | } 28 | 29 | public static void Update(Configuration config, bool forceDisable) 30 | { 31 | bool global = config.global; 32 | bool enabled = config.enabled; 33 | if (forceDisable) 34 | { 35 | enabled = false; 36 | } 37 | try 38 | { 39 | RegistryKey registry = 40 | Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", 41 | true); 42 | if (enabled) 43 | { 44 | if (global) 45 | { 46 | registry.SetValue("ProxyEnable", 1); 47 | registry.SetValue("ProxyServer", "127.0.0.1:" + config.localPort.ToString()); 48 | registry.SetValue("AutoConfigURL", ""); 49 | } 50 | else 51 | { 52 | string pacUrl; 53 | if (config.useOnlinePac && !string.IsNullOrEmpty(config.pacUrl)) 54 | pacUrl = config.pacUrl; 55 | else 56 | pacUrl = "http://127.0.0.1:" + config.localPort.ToString() + "/pac?t=" + GetTimestamp(DateTime.Now); 57 | registry.SetValue("ProxyEnable", 0); 58 | var readProxyServer = registry.GetValue("ProxyServer"); 59 | registry.SetValue("ProxyServer", ""); 60 | registry.SetValue("AutoConfigURL", pacUrl); 61 | } 62 | } 63 | else 64 | { 65 | registry.SetValue("ProxyEnable", 0); 66 | registry.SetValue("ProxyServer", ""); 67 | registry.SetValue("AutoConfigURL", ""); 68 | } 69 | //Set AutoDetectProxy Off 70 | IEAutoDetectProxy(false); 71 | SystemProxy.NotifyIE(); 72 | //Must Notify IE first, or the connections do not chanage 73 | CopyProxySettingFromLan(); 74 | } 75 | catch (Exception e) 76 | { 77 | Logging.LogUsefulException(e); 78 | // TODO this should be moved into views 79 | MessageBox.Show(I18N.GetString("Failed to update registry")); 80 | } 81 | } 82 | 83 | private static void CopyProxySettingFromLan() 84 | { 85 | RegistryKey registry = 86 | Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections", 87 | true); 88 | var defaultValue = registry.GetValue("DefaultConnectionSettings"); 89 | try 90 | { 91 | var connections = registry.GetValueNames(); 92 | foreach (String each in connections) 93 | { 94 | if (!(each.Equals("DefaultConnectionSettings") 95 | || each.Equals("LAN Connection") 96 | || each.Equals("SavedLegacySettings"))) 97 | { 98 | //set all the connections's proxy as the lan 99 | registry.SetValue(each, defaultValue); 100 | } 101 | } 102 | SystemProxy.NotifyIE(); 103 | } catch (IOException e) { 104 | Logging.LogUsefulException(e); 105 | } 106 | } 107 | 108 | private static String GetTimestamp(DateTime value) 109 | { 110 | return value.ToString("yyyyMMddHHmmssffff"); 111 | } 112 | 113 | /// 114 | /// Checks or unchecks the IE Options Connection setting of "Automatically detect Proxy" 115 | /// 116 | /// Provide 'true' if you want to check the 'Automatically detect Proxy' check box. To uncheck, pass 'false' 117 | private static void IEAutoDetectProxy(bool set) 118 | { 119 | RegistryKey registry = 120 | Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections", 121 | true); 122 | byte[] defConnection = (byte[])registry.GetValue("DefaultConnectionSettings"); 123 | byte[] savedLegacySetting = (byte[])registry.GetValue("SavedLegacySettings"); 124 | if (set) 125 | { 126 | defConnection[8] = Convert.ToByte(defConnection[8] & 8); 127 | savedLegacySetting[8] = Convert.ToByte(savedLegacySetting[8] & 8); 128 | } 129 | else 130 | { 131 | defConnection[8] = Convert.ToByte(defConnection[8] & ~8); 132 | savedLegacySetting[8] = Convert.ToByte(savedLegacySetting[8] & ~8); 133 | } 134 | registry.SetValue("DefaultConnectionSettings", defConnection); 135 | registry.SetValue("SavedLegacySettings", savedLegacySetting); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Data/abp.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Data/abp.js.gz -------------------------------------------------------------------------------- /shadowsocks-csharp/Data/cn.txt: -------------------------------------------------------------------------------- 1 | # translation for Simplified Chinese 2 | 3 | Shadowsocks=Shadowsocks 4 | 5 | # Menu items 6 | 7 | Enable System Proxy=启用系统代理 8 | Mode=系统代理模式 9 | PAC=PAC 模式 10 | Global=全局模式 11 | Servers=服务器 12 | Edit Servers...=编辑服务器... 13 | Start on Boot=开机启动 14 | Allow Clients from LAN=允许来自局域网的连接 15 | Local PAC=使用本地 PAC 16 | Online PAC=使用在线 PAC 17 | Edit Local PAC File...=编辑本地 PAC 文件... 18 | Update Local PAC from GFWList=从 GFWList 更新本地 PAC 19 | Edit User Rule for GFWList...=编辑 GFWList 的用户规则... 20 | Show QRCode...=显示二维码... 21 | Scan QRCode from Screen...=扫描屏幕上的二维码... 22 | Availability Statistics=统计可用性 23 | Show Logs...=显示日志... 24 | About...=关于... 25 | Quit=退出 26 | Edit Servers=编辑服务器 27 | Load Balance=负载均衡 28 | High Availability=高可用 29 | Choose By Total Package Loss=累计丢包率 30 | 31 | # Config Form 32 | 33 | &Add=添加(&A) 34 | &Delete=删除(&D) 35 | Server=服务器 36 | Server IP=服务器 IP 37 | Server Port=服务器端口 38 | Password=密码 39 | Encryption=加密 40 | Proxy Port=代理端口 41 | Remarks=备注 42 | OK=确定 43 | Cancel=取消 44 | New server=未配置的服务器 45 | Move &Up=上移(&U) 46 | Move D&own=下移(&O) 47 | 48 | # Log Form 49 | 50 | &File=文件(&F) 51 | &Open Location=在资源管理器中打开(&O) 52 | E&xit=退出(&X) 53 | &Clean logs=清空(&C) 54 | &Font=字体(&F) 55 | &Wrap text=自动换行(&W) 56 | &Top most=置顶(&T) 57 | Log Viewer=日志查看器 58 | 59 | # QRCode Form 60 | 61 | QRCode=二维码 62 | 63 | # PAC Url Form 64 | 65 | Edit Online PAC URL=编辑在线 PAC 网址 66 | Edit Online PAC URL...=编辑在线 PAC 网址... 67 | Please input PAC Url=请输入 PAC 网址 68 | 69 | # Messages 70 | 71 | Shadowsocks Error: {0}=Shadowsocks 错误: {0} 72 | Port already in use=端口已被占用 73 | Illegal port number format=非法端口格式 74 | Please add at least one server=请添加至少一个服务器 75 | Server IP can not be blank=服务器 IP 不能为空 76 | Password can not be blank=密码不能为空 77 | Port out of range=端口超出范围 78 | Port can't be 8123=端口不能为 8123 79 | Shadowsocks {0} Update Found=Shadowsocks {0} 更新 80 | Click here to download=点击这里下载 81 | Shadowsocks is here=Shadowsocks 在这里 82 | You can turn on/off Shadowsocks in the context menu=可以在右键菜单中开关 Shadowsocks 83 | System Proxy Enabled=系统代理已启用 84 | System Proxy Disabled=系统代理未启用 85 | Failed to update PAC file =更新 PAC 文件失败 86 | PAC updated=更新 PAC 成功 87 | No updates found. Please report to GFWList if you have problems with it.=未发现更新。如有问题请提交给 GFWList。 88 | No QRCode found. Try to zoom in or move it to the center of the screen.=未发现二维码,尝试把它放大或移动到靠近屏幕中间的位置 89 | Shadowsocks is already running.=Shadowsocks 已经在运行。 90 | Find Shadowsocks icon in your notify tray.=请在任务栏里寻找 Shadowsocks 图标。 91 | If you want to start multiple Shadowsocks, make a copy in another directory.=如果想同时启动多个,可以另外复制一份到别的目录。 92 | Failed to decode QRCode=无法解析二维码 93 | Failed to update registry=无法修改注册表 94 | System Proxy On: =系统代理已启用: 95 | Running: Port {0}=正在运行:端口 {0} 96 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Data/libsscrypto.dll.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Data/libsscrypto.dll.gz -------------------------------------------------------------------------------- /shadowsocks-csharp/Data/mgwz.dll.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Data/mgwz.dll.gz -------------------------------------------------------------------------------- /shadowsocks-csharp/Data/privoxy.exe.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Data/privoxy.exe.gz -------------------------------------------------------------------------------- /shadowsocks-csharp/Data/privoxy_conf.txt: -------------------------------------------------------------------------------- 1 | listen-address __POLIPO_BIND_IP__:8123 2 | show-on-task-bar 0 3 | activity-animation 0 4 | forward-socks5 / 127.0.0.1:__SOCKS_PORT__ . 5 | hide-console -------------------------------------------------------------------------------- /shadowsocks-csharp/Data/proxy.pac.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Data/proxy.pac.txt.gz -------------------------------------------------------------------------------- /shadowsocks-csharp/Data/user-rule.txt: -------------------------------------------------------------------------------- 1 | ! Put user rules line by line in this file. 2 | ! See https://adblockplus.org/en/filter-cheatsheet 3 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Encryption/EncryptorBase.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography; 2 | using System.Text; 3 | 4 | namespace Shadowsocks.Encryption 5 | { 6 | public abstract class EncryptorBase 7 | : IEncryptor 8 | { 9 | public const int MAX_INPUT_SIZE = 32768; 10 | 11 | protected EncryptorBase(string method, string password) 12 | { 13 | Method = method; 14 | Password = password; 15 | } 16 | 17 | protected string Method; 18 | protected string Password; 19 | 20 | protected byte[] GetPasswordHash() 21 | { 22 | byte[] inputBytes = Encoding.UTF8.GetBytes(Password); 23 | byte[] hash = MD5.Create().ComputeHash(inputBytes); 24 | return hash; 25 | } 26 | 27 | public abstract void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength); 28 | 29 | public abstract void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength); 30 | 31 | public abstract void Dispose(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Encryption/EncryptorFactory.cs: -------------------------------------------------------------------------------- 1 |  2 | using System; 3 | using System.Collections.Generic; 4 | using System.Reflection; 5 | namespace Shadowsocks.Encryption 6 | { 7 | public static class EncryptorFactory 8 | { 9 | private static Dictionary _registeredEncryptors; 10 | 11 | private static Type[] _constructorTypes = new Type[] { typeof(string), typeof(string) }; 12 | 13 | static EncryptorFactory() 14 | { 15 | _registeredEncryptors = new Dictionary(); 16 | foreach (string method in TableEncryptor.SupportedCiphers()) 17 | { 18 | _registeredEncryptors.Add(method, typeof(TableEncryptor)); 19 | } 20 | foreach (string method in PolarSSLEncryptor.SupportedCiphers()) 21 | { 22 | _registeredEncryptors.Add(method, typeof(PolarSSLEncryptor)); 23 | } 24 | foreach (string method in SodiumEncryptor.SupportedCiphers()) 25 | { 26 | _registeredEncryptors.Add(method, typeof(SodiumEncryptor)); 27 | } 28 | } 29 | 30 | public static IEncryptor GetEncryptor(string method, string password) 31 | { 32 | if (string.IsNullOrEmpty(method)) 33 | { 34 | method = "table"; 35 | } 36 | method = method.ToLowerInvariant(); 37 | Type t = _registeredEncryptors[method]; 38 | ConstructorInfo c = t.GetConstructor(_constructorTypes); 39 | IEncryptor result = (IEncryptor)c.Invoke(new object[] { method, password }); 40 | return result; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Encryption/IEncryptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Shadowsocks.Encryption 6 | { 7 | public interface IEncryptor : IDisposable 8 | { 9 | void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength); 10 | void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Encryption/IVEncryptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Security.Cryptography; 4 | using System.Text; 5 | 6 | namespace Shadowsocks.Encryption 7 | { 8 | public abstract class IVEncryptor 9 | : EncryptorBase 10 | { 11 | protected static byte[] tempbuf = new byte[MAX_INPUT_SIZE]; 12 | 13 | protected Dictionary ciphers; 14 | 15 | private static readonly Dictionary CachedKeys = new Dictionary(); 16 | protected byte[] _encryptIV; 17 | protected byte[] _decryptIV; 18 | protected bool _decryptIVReceived; 19 | protected bool _encryptIVSent; 20 | protected int _encryptIVOffset = 0; 21 | protected int _decryptIVOffset = 0; 22 | protected string _method; 23 | protected int _cipher; 24 | protected int[] _cipherInfo; 25 | protected byte[] _key; 26 | protected int keyLen; 27 | protected int ivLen; 28 | 29 | public IVEncryptor(string method, string password) 30 | : base(method, password) 31 | { 32 | InitKey(method, password); 33 | } 34 | 35 | protected abstract Dictionary getCiphers(); 36 | 37 | protected void InitKey(string method, string password) 38 | { 39 | method = method.ToLower(); 40 | _method = method; 41 | string k = method + ":" + password; 42 | ciphers = getCiphers(); 43 | _cipherInfo = ciphers[_method]; 44 | _cipher = _cipherInfo[2]; 45 | if (_cipher == 0) 46 | { 47 | throw new Exception("method not found"); 48 | } 49 | keyLen = ciphers[_method][0]; 50 | ivLen = ciphers[_method][1]; 51 | if (CachedKeys.ContainsKey(k)) 52 | { 53 | _key = CachedKeys[k]; 54 | } 55 | else 56 | { 57 | byte[] passbuf = Encoding.UTF8.GetBytes(password); 58 | _key = new byte[32]; 59 | byte[] iv = new byte[16]; 60 | bytesToKey(passbuf, _key); 61 | CachedKeys[k] = _key; 62 | } 63 | } 64 | 65 | protected void bytesToKey(byte[] password, byte[] key) 66 | { 67 | byte[] result = new byte[password.Length + 16]; 68 | int i = 0; 69 | byte[] md5sum = null; 70 | while (i < key.Length) 71 | { 72 | MD5 md5 = MD5.Create(); 73 | if (i == 0) 74 | { 75 | md5sum = md5.ComputeHash(password); 76 | } 77 | else 78 | { 79 | md5sum.CopyTo(result, 0); 80 | password.CopyTo(result, md5sum.Length); 81 | md5sum = md5.ComputeHash(result); 82 | } 83 | md5sum.CopyTo(key, i); 84 | i += md5sum.Length; 85 | } 86 | } 87 | 88 | protected static void randBytes(byte[] buf, int length) 89 | { 90 | byte[] temp = new byte[length]; 91 | new Random().NextBytes(temp); 92 | temp.CopyTo(buf, 0); 93 | } 94 | 95 | protected virtual void initCipher(byte[] iv, bool isCipher) 96 | { 97 | if (ivLen > 0) 98 | { 99 | if (isCipher) 100 | { 101 | _encryptIV = new byte[ivLen]; 102 | Array.Copy(iv, _encryptIV, ivLen); 103 | } 104 | else 105 | { 106 | _decryptIV = new byte[ivLen]; 107 | Array.Copy(iv, _decryptIV, ivLen); 108 | } 109 | } 110 | } 111 | 112 | protected abstract void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf); 113 | 114 | public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) 115 | { 116 | if (!_encryptIVSent) 117 | { 118 | _encryptIVSent = true; 119 | randBytes(outbuf, ivLen); 120 | initCipher(outbuf, true); 121 | outlength = length + ivLen; 122 | lock (tempbuf) 123 | { 124 | cipherUpdate(true, length, buf, tempbuf); 125 | outlength = length + ivLen; 126 | Buffer.BlockCopy(tempbuf, 0, outbuf, ivLen, length); 127 | } 128 | } 129 | else 130 | { 131 | outlength = length; 132 | cipherUpdate(true, length, buf, outbuf); 133 | } 134 | } 135 | 136 | public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength) 137 | { 138 | if (!_decryptIVReceived) 139 | { 140 | _decryptIVReceived = true; 141 | initCipher(buf, false); 142 | outlength = length - ivLen; 143 | lock (tempbuf) 144 | { 145 | // C# could be multi-threaded 146 | Buffer.BlockCopy(buf, ivLen, tempbuf, 0, length - ivLen); 147 | cipherUpdate(false, length - ivLen, tempbuf, outbuf); 148 | } 149 | } 150 | else 151 | { 152 | outlength = length; 153 | cipherUpdate(false, length, buf, outbuf); 154 | } 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Encryption/PolarSSL.cs: -------------------------------------------------------------------------------- 1 | using Shadowsocks.Controller; 2 | using Shadowsocks.Properties; 3 | using Shadowsocks.Util; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Runtime.InteropServices; 8 | using System.Text; 9 | 10 | namespace Shadowsocks.Encryption 11 | { 12 | public class PolarSSL 13 | { 14 | const string DLLNAME = "libsscrypto"; 15 | 16 | public const int AES_CTX_SIZE = 8 + 4 * 68; 17 | public const int AES_ENCRYPT = 1; 18 | public const int AES_DECRYPT = 0; 19 | 20 | static PolarSSL() 21 | { 22 | string tempPath = Utils.GetTempPath(); 23 | string dllPath = tempPath + "/libsscrypto.dll"; 24 | try 25 | { 26 | FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll); 27 | } 28 | catch (IOException) 29 | { 30 | } 31 | catch (Exception e) 32 | { 33 | Console.WriteLine(e.ToString()); 34 | } 35 | LoadLibrary(dllPath); 36 | } 37 | 38 | [DllImport("Kernel32.dll")] 39 | private static extern IntPtr LoadLibrary(string path); 40 | 41 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] 42 | public extern static void aes_init(IntPtr ctx); 43 | 44 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] 45 | public extern static void aes_free(IntPtr ctx); 46 | 47 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] 48 | public extern static int aes_setkey_enc(IntPtr ctx, byte[] key, int keysize); 49 | 50 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] 51 | public extern static int aes_crypt_cfb128(IntPtr ctx, int mode, int length, ref int iv_off, byte[] iv, byte[] input, byte[] output); 52 | 53 | public const int ARC4_CTX_SIZE = 264; 54 | 55 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] 56 | public extern static void arc4_init(IntPtr ctx); 57 | 58 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] 59 | public extern static void arc4_free(IntPtr ctx); 60 | 61 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] 62 | public extern static void arc4_setup(IntPtr ctx, byte[] key, int keysize); 63 | 64 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] 65 | public extern static int arc4_crypt(IntPtr ctx, int length, byte[] input, byte[] output); 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Encryption/Sodium.cs: -------------------------------------------------------------------------------- 1 | using Shadowsocks.Controller; 2 | using Shadowsocks.Properties; 3 | using Shadowsocks.Util; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Runtime.InteropServices; 8 | using System.Text; 9 | 10 | namespace Shadowsocks.Encryption 11 | { 12 | public class Sodium 13 | { 14 | const string DLLNAME = "libsscrypto"; 15 | 16 | static Sodium() 17 | { 18 | string tempPath = Utils.GetTempPath(); 19 | string dllPath = tempPath + "/libsscrypto.dll"; 20 | try 21 | { 22 | FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll); 23 | LoadLibrary(dllPath); 24 | } 25 | catch (IOException) 26 | { 27 | } 28 | catch (Exception e) 29 | { 30 | Console.WriteLine(e.ToString()); 31 | } 32 | LoadLibrary(dllPath); 33 | } 34 | 35 | [DllImport("Kernel32.dll")] 36 | private static extern IntPtr LoadLibrary(string path); 37 | 38 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] 39 | public extern static void crypto_stream_salsa20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k); 40 | 41 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] 42 | public extern static void crypto_stream_chacha20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Encryption/SodiumEncryptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading; 5 | 6 | namespace Shadowsocks.Encryption 7 | { 8 | public class SodiumEncryptor 9 | : IVEncryptor, IDisposable 10 | { 11 | const int CIPHER_SALSA20 = 1; 12 | const int CIPHER_CHACHA20 = 2; 13 | 14 | const int SODIUM_BLOCK_SIZE = 64; 15 | 16 | static byte[] sodiumBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE]; 17 | 18 | protected int _encryptBytesRemaining; 19 | protected int _decryptBytesRemaining; 20 | protected ulong _encryptIC; 21 | protected ulong _decryptIC; 22 | 23 | public SodiumEncryptor(string method, string password) 24 | : base(method, password) 25 | { 26 | InitKey(method, password); 27 | } 28 | 29 | private static Dictionary _ciphers = new Dictionary { 30 | {"salsa20", new int[]{32, 8, CIPHER_SALSA20, PolarSSL.AES_CTX_SIZE}}, 31 | {"chacha20", new int[]{32, 8, CIPHER_CHACHA20, PolarSSL.AES_CTX_SIZE}}, 32 | }; 33 | 34 | protected override Dictionary getCiphers() 35 | { 36 | return _ciphers; 37 | } 38 | 39 | public static List SupportedCiphers() 40 | { 41 | return new List(_ciphers.Keys); 42 | } 43 | 44 | protected override void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf) 45 | { 46 | // TODO write a unidirection cipher so we don't have to if if if 47 | int bytesRemaining; 48 | ulong ic; 49 | byte[] iv; 50 | 51 | // I'm tired. just add a big lock 52 | // let's optimize for RAM instead of CPU 53 | lock(sodiumBuf) 54 | { 55 | if (isCipher) 56 | { 57 | bytesRemaining = _encryptBytesRemaining; 58 | ic = _encryptIC; 59 | iv = _encryptIV; 60 | } 61 | else 62 | { 63 | bytesRemaining = _decryptBytesRemaining; 64 | ic = _decryptIC; 65 | iv = _decryptIV; 66 | } 67 | int padding = bytesRemaining; 68 | Buffer.BlockCopy(buf, 0, sodiumBuf, padding, length); 69 | 70 | switch (_cipher) 71 | { 72 | case CIPHER_SALSA20: 73 | Sodium.crypto_stream_salsa20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key); 74 | break; 75 | case CIPHER_CHACHA20: 76 | Sodium.crypto_stream_chacha20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key); 77 | break; 78 | } 79 | Buffer.BlockCopy(sodiumBuf, padding, outbuf, 0, length); 80 | padding += length; 81 | ic += (ulong)padding / SODIUM_BLOCK_SIZE; 82 | bytesRemaining = padding % SODIUM_BLOCK_SIZE; 83 | 84 | if (isCipher) 85 | { 86 | _encryptBytesRemaining = bytesRemaining; 87 | _encryptIC = ic; 88 | } 89 | else 90 | { 91 | _decryptBytesRemaining = bytesRemaining; 92 | _decryptIC = ic; 93 | } 94 | } 95 | } 96 | 97 | public override void Dispose() 98 | { 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Encryption/TableEncryptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Shadowsocks.Encryption 5 | { 6 | public class TableEncryptor 7 | : EncryptorBase 8 | { 9 | public TableEncryptor(string method, string password) 10 | : base(method, password) 11 | { 12 | byte[] hash = GetPasswordHash(); 13 | // TODO endian 14 | ulong a = BitConverter.ToUInt64(hash, 0); 15 | for (int i = 0; i < 256; i++) 16 | { 17 | _encryptTable[i] = (byte)i; 18 | } 19 | for (int i = 1; i < 1024; i++) 20 | { 21 | _encryptTable = MergeSort(_encryptTable, a, i); 22 | } 23 | for (int i = 0; i < 256; i++) 24 | { 25 | _decryptTable[_encryptTable[i]] = (byte)i; 26 | } 27 | } 28 | 29 | public static List SupportedCiphers() 30 | { 31 | return new List(new string[]{"table"}); 32 | } 33 | 34 | public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) 35 | { 36 | byte[] result = new byte[length]; 37 | for (int i = 0; i < length; i++) 38 | { 39 | outbuf[i] = _encryptTable[buf[i]]; 40 | } 41 | outlength = length; 42 | } 43 | 44 | public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength) 45 | { 46 | byte[] result = new byte[length]; 47 | for (int i = 0; i < length; i++) 48 | { 49 | outbuf[i] = _decryptTable[buf[i]]; 50 | } 51 | outlength = length; 52 | } 53 | 54 | private readonly byte[] _encryptTable = new byte[256]; 55 | private readonly byte[] _decryptTable = new byte[256]; 56 | 57 | private static long Compare(byte x, byte y, ulong a, int i) 58 | { 59 | return (long)(a % (ulong)(x + i)) - (long)(a % (ulong)(y + i)); 60 | } 61 | 62 | private byte[] MergeSort(byte[] array, ulong a, int j) 63 | { 64 | if (array.Length == 1) 65 | { 66 | return array; 67 | } 68 | int middle = array.Length / 2; 69 | byte[] left = new byte[middle]; 70 | for (int i = 0; i < middle; i++) 71 | { 72 | left[i] = array[i]; 73 | } 74 | byte[] right = new byte[array.Length - middle]; 75 | for (int i = 0; i < array.Length - middle; i++) 76 | { 77 | right[i] = array[i + middle]; 78 | } 79 | left = MergeSort(left, a, j); 80 | right = MergeSort(right, a, j); 81 | 82 | int leftptr = 0; 83 | int rightptr = 0; 84 | 85 | byte[] sorted = new byte[array.Length]; 86 | for (int k = 0; k < array.Length; k++) 87 | { 88 | if (rightptr == right.Length || ((leftptr < left.Length) && (Compare(left[leftptr], right[rightptr], a, j) <= 0))) 89 | { 90 | sorted[k] = left[leftptr]; 91 | leftptr++; 92 | } 93 | else if (leftptr == left.Length || ((rightptr < right.Length) && (Compare(right[rightptr], left[leftptr], a, j)) <= 0)) 94 | { 95 | sorted[k] = right[rightptr]; 96 | rightptr++; 97 | } 98 | } 99 | return sorted; 100 | } 101 | 102 | public override void Dispose() 103 | { 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Model/Configuration.cs: -------------------------------------------------------------------------------- 1 | using Shadowsocks.Controller; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Text; 6 | using System.Windows.Forms; 7 | 8 | namespace Shadowsocks.Model 9 | { 10 | [Serializable] 11 | public class Configuration 12 | { 13 | public List configs; 14 | 15 | // when strategy is set, index is ignored 16 | public string strategy; 17 | public int index; 18 | public bool global; 19 | public bool enabled; 20 | public bool shareOverLan; 21 | public bool isDefault; 22 | public int localPort; 23 | public string pacUrl; 24 | public bool useOnlinePac; 25 | public bool availabilityStatistics; 26 | 27 | private static string CONFIG_FILE = "gui-config.json"; 28 | 29 | public Server GetCurrentServer() 30 | { 31 | if (index >= 0 && index < configs.Count) 32 | { 33 | return configs[index]; 34 | } 35 | else 36 | { 37 | return GetDefaultServer(); 38 | } 39 | } 40 | 41 | public static void CheckServer(Server server) 42 | { 43 | CheckPort(server.server_port); 44 | CheckPassword(server.password); 45 | CheckServer(server.server); 46 | } 47 | 48 | public static Configuration Load() 49 | { 50 | try 51 | { 52 | string configContent = File.ReadAllText(CONFIG_FILE); 53 | Configuration config = SimpleJson.SimpleJson.DeserializeObject(configContent, new JsonSerializerStrategy()); 54 | config.isDefault = false; 55 | if (config.localPort == 0) 56 | { 57 | config.localPort = 1080; 58 | } 59 | if (config.index == -1) 60 | { 61 | if (config.strategy == null) 62 | { 63 | config.index = 0; 64 | } 65 | } 66 | return config; 67 | } 68 | catch (Exception e) 69 | { 70 | if (!(e is FileNotFoundException)) 71 | { 72 | Console.WriteLine(e); 73 | } 74 | return new Configuration 75 | { 76 | index = 0, 77 | isDefault = true, 78 | localPort = 1080, 79 | configs = new List() 80 | { 81 | GetDefaultServer() 82 | } 83 | }; 84 | } 85 | } 86 | 87 | public static void Save(Configuration config) 88 | { 89 | if (config.index >= config.configs.Count) 90 | { 91 | config.index = config.configs.Count - 1; 92 | } 93 | if (config.index < -1) 94 | { 95 | config.index = -1; 96 | } 97 | if (config.index == -1) 98 | { 99 | if (config.strategy == null) 100 | { 101 | config.index = 0; 102 | } 103 | } 104 | config.isDefault = false; 105 | try 106 | { 107 | using (StreamWriter sw = new StreamWriter(File.Open(CONFIG_FILE, FileMode.Create))) 108 | { 109 | string jsonString = SimpleJson.SimpleJson.SerializeObject(config); 110 | sw.Write(jsonString); 111 | sw.Flush(); 112 | } 113 | } 114 | catch (IOException e) 115 | { 116 | Console.Error.WriteLine(e); 117 | } 118 | } 119 | 120 | public static Server GetDefaultServer() 121 | { 122 | return new Server(); 123 | } 124 | 125 | private static void Assert(bool condition) 126 | { 127 | if (!condition) 128 | { 129 | throw new Exception(I18N.GetString("assertion failure")); 130 | } 131 | } 132 | 133 | public static void CheckPort(int port) 134 | { 135 | if (port <= 0 || port > 65535) 136 | { 137 | throw new ArgumentException(I18N.GetString("Port out of range")); 138 | } 139 | } 140 | 141 | public static void CheckLocalPort(int port) 142 | { 143 | CheckPort(port); 144 | if (port == 8123) 145 | { 146 | throw new ArgumentException(I18N.GetString("Port can't be 8123")); 147 | } 148 | } 149 | 150 | private static void CheckPassword(string password) 151 | { 152 | if (string.IsNullOrEmpty(password)) 153 | { 154 | throw new ArgumentException(I18N.GetString("Password can not be blank")); 155 | } 156 | } 157 | 158 | private static void CheckServer(string server) 159 | { 160 | if (string.IsNullOrEmpty(server)) 161 | { 162 | throw new ArgumentException(I18N.GetString("Server IP can not be blank")); 163 | } 164 | } 165 | 166 | private class JsonSerializerStrategy : SimpleJson.PocoJsonSerializerStrategy 167 | { 168 | // convert string to int 169 | public override object DeserializeObject(object value, Type type) 170 | { 171 | if (type == typeof(Int32) && value.GetType() == typeof(string)) 172 | { 173 | return Int32.Parse(value.ToString()); 174 | } 175 | return base.DeserializeObject(value, type); 176 | } 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Model/Server.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.IO; 5 | using System.Diagnostics; 6 | using SimpleJson; 7 | using Shadowsocks.Controller; 8 | using System.Text.RegularExpressions; 9 | 10 | namespace Shadowsocks.Model 11 | { 12 | [Serializable] 13 | public class Server 14 | { 15 | public string server; 16 | public int server_port; 17 | public string password; 18 | public string method; 19 | public string remarks; 20 | 21 | public override int GetHashCode() 22 | { 23 | return server.GetHashCode() ^ server_port; 24 | } 25 | 26 | public override bool Equals(object obj) 27 | { 28 | Server o2 = (Server)obj; 29 | return this.server == o2.server && this.server_port == o2.server_port; 30 | } 31 | 32 | public string FriendlyName() 33 | { 34 | if (string.IsNullOrEmpty(server)) 35 | { 36 | return I18N.GetString("New server"); 37 | } 38 | if (string.IsNullOrEmpty(remarks)) 39 | { 40 | return server + ":" + server_port; 41 | } 42 | else 43 | { 44 | return remarks + " (" + server + ":" + server_port + ")"; 45 | } 46 | } 47 | 48 | public Server() 49 | { 50 | this.server = ""; 51 | this.server_port = 8388; 52 | this.method = "aes-256-cfb"; 53 | this.password = ""; 54 | this.remarks = ""; 55 | } 56 | 57 | public Server(string ssURL) : this() 58 | { 59 | string[] r1 = Regex.Split(ssURL, "ss://", RegexOptions.IgnoreCase); 60 | string base64 = r1[1].ToString(); 61 | byte[] bytes = null; 62 | for (var i = 0; i < 3; i++) 63 | { 64 | try 65 | { 66 | bytes = System.Convert.FromBase64String(base64); 67 | } 68 | catch (FormatException) 69 | { 70 | base64 += "="; 71 | } 72 | } 73 | if (bytes == null) 74 | { 75 | throw new FormatException(); 76 | } 77 | try 78 | { 79 | string data = Encoding.UTF8.GetString(bytes); 80 | int indexLastAt = data.LastIndexOf('@'); 81 | 82 | string afterAt = data.Substring(indexLastAt + 1); 83 | int indexLastColon = afterAt.LastIndexOf(':'); 84 | this.server_port = int.Parse(afterAt.Substring(indexLastColon + 1)); 85 | this.server = afterAt.Substring(0, indexLastColon); 86 | 87 | string beforeAt = data.Substring(0, indexLastAt); 88 | string[] parts = beforeAt.Split(new[] { ':' }); 89 | this.method = parts[0]; 90 | this.password = parts[1]; 91 | } 92 | catch (IndexOutOfRangeException) 93 | { 94 | throw new FormatException(); 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Program.cs: -------------------------------------------------------------------------------- 1 | using Shadowsocks.Controller; 2 | using Shadowsocks.Properties; 3 | using Shadowsocks.View; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Diagnostics; 7 | using System.IO; 8 | using System.Threading; 9 | using System.Windows.Forms; 10 | 11 | namespace Shadowsocks 12 | { 13 | static class Program 14 | { 15 | /// 16 | /// 应用程序的主入口点。 17 | /// 18 | [STAThread] 19 | static void Main() 20 | { 21 | Util.Utils.ReleaseMemory(true); 22 | using (Mutex mutex = new Mutex(false, "Global\\Shadowsocks_" + Application.StartupPath.GetHashCode())) 23 | { 24 | Application.EnableVisualStyles(); 25 | Application.SetCompatibleTextRenderingDefault(false); 26 | 27 | if (!mutex.WaitOne(0, false)) 28 | { 29 | Process[] oldProcesses = Process.GetProcessesByName("Shadowsocks"); 30 | if (oldProcesses.Length > 0) 31 | { 32 | Process oldProcess = oldProcesses[0]; 33 | } 34 | MessageBox.Show(I18N.GetString("Find Shadowsocks icon in your notify tray.") + "\n" + 35 | I18N.GetString("If you want to start multiple Shadowsocks, make a copy in another directory."), 36 | I18N.GetString("Shadowsocks is already running.")); 37 | return; 38 | } 39 | Directory.SetCurrentDirectory(Application.StartupPath); 40 | #if !DEBUG 41 | Logging.OpenLogFile(); 42 | #endif 43 | ShadowsocksController controller = new ShadowsocksController(); 44 | 45 | MenuViewController viewController = new MenuViewController(controller); 46 | 47 | controller.Start(); 48 | 49 | Application.Run(); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using Shadowsocks.Controller; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // 有关程序集的常规信息通过下列属性集 7 | // 控制。更改这些属性值可修改 8 | // 与程序集关联的信息。 9 | [assembly: AssemblyTitle("Shadowsocks")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("Shadowsocks")] 14 | [assembly: AssemblyCopyright("Copyright © clowwindy 2015")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // 将 ComVisible 设置为 false 使此程序集中的类型 19 | // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, 20 | // 则将该类型上的 ComVisible 属性设置为 true。 21 | [assembly: ComVisible(false)] 22 | 23 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 24 | [assembly: Guid("f8334709-4309-436a-8bbd-6165dcf4a660")] 25 | 26 | // 程序集的版本信息由下面四个值组成: 27 | // 28 | // 主版本 29 | // 次版本 30 | // 内部版本号 31 | // 修订号 32 | // 33 | // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, 34 | // 方法是按如下所示使用“*”: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion(UpdateChecker.Version)] 37 | // [assembly: AssemblyFileVersion("2.0.0")] 38 | -------------------------------------------------------------------------------- /shadowsocks-csharp/Resources/ss16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Resources/ss16.png -------------------------------------------------------------------------------- /shadowsocks-csharp/Resources/ss20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Resources/ss20.png -------------------------------------------------------------------------------- /shadowsocks-csharp/Resources/ss24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Resources/ss24.png -------------------------------------------------------------------------------- /shadowsocks-csharp/Resources/ssw128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Resources/ssw128.png -------------------------------------------------------------------------------- /shadowsocks-csharp/Util/Util.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.IO.Compression; 6 | using System.Runtime.InteropServices; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | namespace Shadowsocks.Util 11 | { 12 | public class Utils 13 | { 14 | // return path to store temporary files 15 | public static string GetTempPath() 16 | { 17 | if (File.Exists(Application.StartupPath + "\\shadowsocks_portable_mode.txt")) 18 | { 19 | try 20 | { 21 | Directory.CreateDirectory(Application.StartupPath + "\\temp"); 22 | } catch (Exception e) 23 | { 24 | Console.WriteLine(e); 25 | } 26 | // don't use "/", it will fail when we call explorer /select xxx/temp\xxx.log 27 | return Application.StartupPath + "\\temp"; 28 | } 29 | return Path.GetTempPath(); 30 | } 31 | 32 | public static void ReleaseMemory(bool removePages) 33 | { 34 | // release any unused pages 35 | // making the numbers look good in task manager 36 | // this is totally nonsense in programming 37 | // but good for those users who care 38 | // making them happier with their everyday life 39 | // which is part of user experience 40 | GC.Collect(GC.MaxGeneration); 41 | GC.WaitForPendingFinalizers(); 42 | if (removePages) 43 | { 44 | // as some users have pointed out 45 | // removing pages from working set will cause some IO 46 | // which lowered user experience for another group of users 47 | // 48 | // so we do 2 more things here to satisfy them: 49 | // 1. only remove pages once when configuration is changed 50 | // 2. add more comments here to tell users that calling 51 | // this function will not be more frequent than 52 | // IM apps writing chat logs, or web browsers writing cache files 53 | // if they're so concerned about their disk, they should 54 | // uninstall all IM apps and web browsers 55 | // 56 | // please open an issue if you're worried about anything else in your computer 57 | // no matter it's GPU performance, monitor contrast, audio fidelity 58 | // or anything else in the task manager 59 | // we'll do as much as we can to help you 60 | // 61 | // just kidding 62 | SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, 63 | (UIntPtr)0xFFFFFFFF, (UIntPtr)0xFFFFFFFF); 64 | } 65 | } 66 | 67 | public static string UnGzip(byte[] buf) 68 | { 69 | byte[] buffer = new byte[1024]; 70 | int n; 71 | using (MemoryStream sb = new MemoryStream()) 72 | { 73 | using (GZipStream input = new GZipStream(new MemoryStream(buf), 74 | CompressionMode.Decompress, false)) 75 | { 76 | while ((n = input.Read(buffer, 0, buffer.Length)) > 0) 77 | { 78 | sb.Write(buffer, 0, n); 79 | } 80 | } 81 | return System.Text.Encoding.UTF8.GetString(sb.ToArray()); 82 | } 83 | } 84 | 85 | [DllImport("kernel32.dll")] 86 | [return: MarshalAs(UnmanagedType.Bool)] 87 | private static extern bool SetProcessWorkingSetSize(IntPtr process, 88 | UIntPtr minimumWorkingSetSize, UIntPtr maximumWorkingSetSize); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /shadowsocks-csharp/View/ConfigForm.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 | -------------------------------------------------------------------------------- /shadowsocks-csharp/View/LogForm.cs: -------------------------------------------------------------------------------- 1 | using Shadowsocks.Controller; 2 | using Shadowsocks.Properties; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | using System.Data; 7 | using System.Drawing; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Windows.Forms; 12 | 13 | namespace Shadowsocks.View 14 | { 15 | public partial class LogForm : Form 16 | { 17 | long lastOffset; 18 | string filename; 19 | Timer timer; 20 | const int BACK_OFFSET = 65536; 21 | 22 | public LogForm(string filename) 23 | { 24 | this.filename = filename; 25 | InitializeComponent(); 26 | this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); 27 | 28 | UpdateTexts(); 29 | } 30 | 31 | private void UpdateTexts() 32 | { 33 | FileMenuItem.Text = I18N.GetString("&File"); 34 | OpenLocationMenuItem.Text = I18N.GetString("&Open Location"); 35 | ExitMenuItem.Text = I18N.GetString("E&xit"); 36 | CleanLogsButton.Text = I18N.GetString("&Clean logs"); 37 | ChangeFontButton.Text = I18N.GetString("&Font"); 38 | WrapTextCheckBox.Text = I18N.GetString("&Wrap text"); 39 | TopMostCheckBox.Text = I18N.GetString("&Top most"); 40 | this.Text = I18N.GetString("Log Viewer"); 41 | } 42 | 43 | private void Timer_Tick(object sender, EventArgs e) 44 | { 45 | UpdateContent(); 46 | } 47 | 48 | private void InitContent() 49 | { 50 | using (StreamReader reader = new StreamReader(new FileStream(filename, 51 | FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) 52 | { 53 | if (reader.BaseStream.Length > BACK_OFFSET) 54 | { 55 | reader.BaseStream.Seek(-BACK_OFFSET, SeekOrigin.End); 56 | reader.ReadLine(); 57 | } 58 | 59 | string line = ""; 60 | while ((line = reader.ReadLine()) != null) 61 | LogMessageTextBox.AppendText(line + "\r\n"); 62 | 63 | LogMessageTextBox.ScrollToCaret(); 64 | 65 | lastOffset = reader.BaseStream.Position; 66 | } 67 | } 68 | 69 | private void UpdateContent() 70 | { 71 | using (StreamReader reader = new StreamReader(new FileStream(filename, 72 | FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) 73 | { 74 | reader.BaseStream.Seek(lastOffset, SeekOrigin.Begin); 75 | 76 | string line = ""; 77 | bool changed = false; 78 | while ((line = reader.ReadLine()) != null) 79 | { 80 | changed = true; 81 | LogMessageTextBox.AppendText(line + "\r\n"); 82 | } 83 | 84 | if (changed) 85 | { 86 | LogMessageTextBox.ScrollToCaret(); 87 | } 88 | 89 | lastOffset = reader.BaseStream.Position; 90 | } 91 | } 92 | 93 | private void LogForm_Load(object sender, EventArgs e) 94 | { 95 | InitContent(); 96 | timer = new Timer(); 97 | timer.Interval = 300; 98 | timer.Tick += Timer_Tick; 99 | timer.Start(); 100 | } 101 | 102 | private void LogForm_FormClosing(object sender, FormClosingEventArgs e) 103 | { 104 | timer.Stop(); 105 | } 106 | 107 | private void OpenLocationMenuItem_Click(object sender, EventArgs e) 108 | { 109 | string argument = "/select, \"" + filename + "\""; 110 | Console.WriteLine(argument); 111 | System.Diagnostics.Process.Start("explorer.exe", argument); 112 | } 113 | 114 | private void ExitMenuItem_Click(object sender, EventArgs e) 115 | { 116 | this.Close(); 117 | } 118 | 119 | private void LogForm_Shown(object sender, EventArgs e) 120 | { 121 | LogMessageTextBox.ScrollToCaret(); 122 | } 123 | 124 | private void WrapTextCheckBox_CheckedChanged(object sender, EventArgs e) 125 | { 126 | LogMessageTextBox.WordWrap = WrapTextCheckBox.Checked; 127 | LogMessageTextBox.ScrollToCaret(); 128 | } 129 | 130 | private void CleanLogsButton_Click(object sender, EventArgs e) 131 | { 132 | LogMessageTextBox.Clear(); 133 | } 134 | 135 | private void ChangeFontButton_Click(object sender, EventArgs e) 136 | { 137 | FontDialog fd = new FontDialog(); 138 | fd.Font = LogMessageTextBox.Font; 139 | if (fd.ShowDialog() == DialogResult.OK) 140 | { 141 | LogMessageTextBox.Font = fd.Font; 142 | } 143 | } 144 | 145 | private void TopMostCheckBox_CheckedChanged(object sender, EventArgs e) 146 | { 147 | this.TopMost = TopMostCheckBox.Checked; 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /shadowsocks-csharp/View/LogForm.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 | 124 | 172, 17 125 | 126 | -------------------------------------------------------------------------------- /shadowsocks-csharp/View/QRCodeForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Shadowsocks.View 2 | { 3 | partial class QRCodeForm 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.pictureBox1 = new System.Windows.Forms.PictureBox(); 32 | this.listBox1 = new System.Windows.Forms.ListBox(); 33 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); 34 | this.SuspendLayout(); 35 | // 36 | // pictureBox1 37 | // 38 | this.pictureBox1.Location = new System.Drawing.Point(10, 10); 39 | this.pictureBox1.Margin = new System.Windows.Forms.Padding(0); 40 | this.pictureBox1.Name = "pictureBox1"; 41 | this.pictureBox1.Size = new System.Drawing.Size(210, 210); 42 | this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; 43 | this.pictureBox1.TabIndex = 1; 44 | this.pictureBox1.TabStop = false; 45 | // 46 | // listBox1 47 | // 48 | this.listBox1.DisplayMember = "Value"; 49 | this.listBox1.FormattingEnabled = true; 50 | this.listBox1.ItemHeight = 12; 51 | this.listBox1.Location = new System.Drawing.Point(224, 10); 52 | this.listBox1.Name = "listBox1"; 53 | this.listBox1.ScrollAlwaysVisible = true; 54 | this.listBox1.Size = new System.Drawing.Size(227, 208); 55 | this.listBox1.TabIndex = 2; 56 | this.listBox1.ValueMember = "Key"; 57 | this.listBox1.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged); 58 | // 59 | // QRCodeForm 60 | // 61 | this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); 62 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; 63 | this.AutoSize = true; 64 | this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 65 | this.BackColor = System.Drawing.Color.White; 66 | this.ClientSize = new System.Drawing.Size(457, 228); 67 | this.Controls.Add(this.listBox1); 68 | this.Controls.Add(this.pictureBox1); 69 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 70 | this.MaximizeBox = false; 71 | this.MinimizeBox = false; 72 | this.Name = "QRCodeForm"; 73 | this.Padding = new System.Windows.Forms.Padding(10); 74 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 75 | this.Text = "QRCode"; 76 | this.Load += new System.EventHandler(this.QRCodeForm_Load); 77 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); 78 | this.ResumeLayout(false); 79 | 80 | } 81 | 82 | #endregion 83 | 84 | private System.Windows.Forms.PictureBox pictureBox1; 85 | private System.Windows.Forms.ListBox listBox1; 86 | } 87 | } -------------------------------------------------------------------------------- /shadowsocks-csharp/View/QRCodeForm.cs: -------------------------------------------------------------------------------- 1 | using ZXing.QrCode.Internal; 2 | using Shadowsocks.Controller; 3 | using Shadowsocks.Properties; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.ComponentModel; 7 | using System.Data; 8 | using System.Drawing; 9 | using System.IO; 10 | using System.IO.Compression; 11 | using System.Linq; 12 | using System.Text; 13 | using System.Windows.Forms; 14 | using Shadowsocks.Model; 15 | 16 | namespace Shadowsocks.View 17 | { 18 | public partial class QRCodeForm : Form 19 | { 20 | private string code; 21 | 22 | public QRCodeForm(string code) 23 | { 24 | this.code = code; 25 | InitializeComponent(); 26 | this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); 27 | this.Text = I18N.GetString("QRCode"); 28 | } 29 | 30 | private void GenQR(string ssconfig) 31 | { 32 | string qrText = ssconfig; 33 | QRCode code = ZXing.QrCode.Internal.Encoder.encode(qrText, ErrorCorrectionLevel.M); 34 | ByteMatrix m = code.Matrix; 35 | int blockSize = Math.Max(pictureBox1.Height/m.Height, 1); 36 | Bitmap drawArea = new Bitmap((m.Width*blockSize), (m.Height*blockSize)); 37 | using (Graphics g = Graphics.FromImage(drawArea)) 38 | { 39 | g.Clear(Color.White); 40 | using (Brush b = new SolidBrush(Color.Black)) 41 | { 42 | for (int row = 0; row < m.Width; row++) 43 | { 44 | for (int col = 0; col < m.Height; col++) 45 | { 46 | if (m[row, col] != 0) 47 | { 48 | g.FillRectangle(b, blockSize*row, blockSize*col, blockSize, blockSize); 49 | } 50 | } 51 | } 52 | } 53 | } 54 | pictureBox1.Image = drawArea; 55 | } 56 | 57 | private void QRCodeForm_Load(object sender, EventArgs e) 58 | { 59 | var servers = Configuration.Load(); 60 | var serverDatas = servers.configs.Select( 61 | server => 62 | new KeyValuePair(ShadowsocksController.GetQRCode(server), server.FriendlyName()) 63 | ).ToList(); 64 | listBox1.DataSource = serverDatas; 65 | 66 | var selectIndex = serverDatas.FindIndex(serverData => serverData.Key.StartsWith(code)); 67 | if (selectIndex >= 0) listBox1.SetSelected(selectIndex, true); 68 | } 69 | 70 | private void listBox1_SelectedIndexChanged(object sender, EventArgs e) 71 | { 72 | GenQR((sender as ListBox)?.SelectedValue.ToString()); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /shadowsocks-csharp/View/QRCodeForm.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 | -------------------------------------------------------------------------------- /shadowsocks-csharp/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /shadowsocks-csharp/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | true 14 | 15 | 16 | -------------------------------------------------------------------------------- /shadowsocks-csharp/shadowsocks.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/shadowsocks.ico -------------------------------------------------------------------------------- /test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("test")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f74e87ac-7e3a-444b-a1d9-8b91a674c60f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /test/test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {45913187-0685-4903-B250-DCEF0479CD86} 7 | Library 8 | Properties 9 | test 10 | test 11 | v4.5 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | 21 | 22 | bin\x86\Debug\ 23 | x86 24 | 25 | 26 | bin\x86\Release\ 27 | x86 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | {8c02d2f7-7cdb-4d55-9f25-cd03ef4aa062} 54 | shadowsocks-csharp 55 | 56 | 57 | 58 | 59 | 60 | 61 | False 62 | 63 | 64 | False 65 | 66 | 67 | False 68 | 69 | 70 | False 71 | 72 | 73 | 74 | 75 | 76 | 77 | 84 | --------------------------------------------------------------------------------